1、需求
使用springmvc和mybatis完成商品列表查询
2、整合思路
springMvc和Mybatis的系统架构
2.1、工程结构
2.2、整合持久层
mybatis和springmvc整合。通过spring管理mapper接口,使用mapper的扫描器自动扫描
mapper接口在spring中注册。
2.2.1、sqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 全局setting -->
<!-- 配置别名 -->
<typeAliases>
<!-- 批量扫描包 -->
<package name="com.shuai.pojo"/>
</typeAliases>
<!-- 配置mapper
由于使用spring和mybatis的整合包进行mapper扫描,这里不需要配置
注意:必须遵循mapper.xml和mapper.java文件同名且在同一个目录
-->
</configuration>
2.2.2、配置applicationContext-dao.xml
需要配置数据源、sqlSessionFactory、mapper扫描器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd ">
<!-- 加载db.properties文件 db.properties的key命名有一定规则-->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 配置数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- 配置sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入数据源 -->
<property name="dataSource" ref="dataSource"/>
<!-- 加载mybatis全局配置文件 -->
<property name="configLocation" value="classpath:mybatis/sqlMapConfig.xml"/>
</bean>
<!-- 配置mapper的扫描器 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 批量扫描mapper 多个包用,隔开-->
<property name="basePackage" value="com.shuai.mapper"/>
<!-- 注入sqlSessionFactory -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
</beans>
2.2.3、使用mybatis逆向工程创建pojo与mapper.xml,mapper接口
(1)逆向工程需要的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- mybatis逆向工程的配置文件 -->
<context id="testTables" targetRuntime="MyBatis3">
<commentGenerator>
<!-- 是否取消自动生成的注释true:是false:否 -->
<property name="suppressAllComments" value="false"/>
</commentGenerator>
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC"
userId="root"
password="root">
<property name="nullCatalogMeansCurrent" value="true"/>
</jdbcConnection>
<!-- 默认false,把jdbc decimal和numberic类型解析为Integer,为true把jdbc decimal和numberic类型解析为java BigDecimal -->
<javaTypeResolver >
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- 生成 pojo的位置 -->
<javaModelGenerator targetPackage="com.guai.pojo" targetProject=".\src">
<!-- 是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="true" />
<!-- 从数据库返回的值域清理空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- mapper.xml文件的位置 -->
<sqlMapGenerator targetPackage="com.guai.mapper" targetProject=".\src">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- mapper接口的位置 -->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.guai.mapper" targetProject=".\src">
<property name="enableSubPackages" value="true" />
</javaClientGenerator>
<!-- 指定数据库表 -->
<table tableName="items"/>
<table tableName="order_detail"/>
<table tableName="orders"/>
<table tableName="user"/>
<!-- 指定字段的java类型 -->
<!-- <columnOverride column="number" javaType="String"/>
</table>
-->
<!-- <table schema="DB2ADMIN" tableName="ALLTYPES" domainObjectName="Customer" >
<property name="useActualColumnNames" value="true"/>
<generatedKey column="ID" sqlStatement="DB2" identity="true" />
<columnOverride column="DATE_FIELD" property="startDate" />
<ignoreColumn column="FRED" />
<columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" />
</table> -->
</context>
</generatorConfiguration>
(2)逆向工程执行方法:
/**
* mybatis逆向工程 生成mapper接口,mapper,pojo
* @author guai
*
*/
public class GeneratorTest {
public static void main(String[] args) {
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
//指定配置文件 其余不用修改
File configFile = new File("./config/mybatis/generatorConfig.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
try {
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
(3)生成的文件
(4)选择需要的文件复制到指定的包中(最好不要直接生成到开发项目包中,因为可能导致同名文件覆盖等问题)复制到指定包中记得修改包路径
注意:要将接口的名称与xml文件保持一致(批量扫描要遵循的规则)
2.2.4、自定义一个商品查询mapper
针对综合查询mapper,一般情况会有关联查询,建议自定义一个mapper
(1) 定义 商品的包装类(即里面包装了一个数据实体类)
作用:对原本的实体类进行属性扩展
package com.shuai.pojo;
/**
* 商品的包装类(即里面包装了一个数据实体)
* @author guai
*
*/
public class ItemsVo {
//商品信息
private Items items;
/*为了系统的可扩展性 一般对原始生成的po进行扩展*/
private ItemsCustome itemsCustome;
……setter and getter
}
对原生po扩展的类
/**
* 商品信息的扩展类
* @author guai
*
*/
public class ItemsCustome extends Items{
//添加扩展属性
private String extendedAttribute;
……setter and getter
}
原生po类
public class Items {
private Integer id;
private String name;
private Float price;
private String detail;
private String pic;
private Date createtime;
……setter and getter
}
额:为啥要弄个扩展类继承原生pojo再把扩展类放到包装类里呢??
额,1、当数据库表发生改变时需要重新逆向工程生成pojo若直接在远程pojo中扩展则扩展信息会被覆盖
2、为啥不直接在包装类中扩展,包装类中可以扩展,但是对那些针对性强的属性最好不要直接放到包装类中,否则会导致可读性差。比如给商品扩展一个生产日期,对于生产日期一般只有商品有,最好直接放到商品信息的扩展类中。
当然在一般的项目开发中当数据比较少且简单则根据需求选择合适的方法。
(2)自定义ItemsMapperCustom.xml (mapper.xml)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.guai.mapper.ItemsMapperCustome">
<!-- 定义sql片段 -->
<sql id="select_items_where">
<!-- 使用动态sql,通过if满足条件进行sql拼接 -->
<!-- 商品的查询条件通过ItemsVo包装对象itemsCustom属性传递 -->
<if test="itemsCustome.name!=null and itemsCustome.name!='' ">
items.name like '%${itemsCustome.name}%'
</if>
</sql>
<!-- 商品列表查询
parameterType传入包装对象(包装了查询条件)
resultType 建议使用扩展对象
-->
<select id="selectItemsList" parameterType="com.shuai.pojo.ItemsVo"
resultType="com.shuai.pojo.ItemsCustome">
<where>
<!-- 引用sql片段 -->
<include refid="select_items_where"/>
</where>
</select>
</mapper>
(3)ItemsMapperCustom.java (mapper接口)
package com.shuai.mapper;
import java.util.List;
import com.shuai.pojo.*;
public interface ItemsMapperCustome {
public List<ItemsCustome> selectItemsList(ItemsVo itemsVo)throws Exception;
}
2.3、整合service
通过spring管理service接口。
使用配置方式将service接口配置在spring配置文件中。实现事务控制。
2.3.1、定义service接口
/**
* 商品管理的service
* @author guai
*
*/
public interface ItemsService {
/**
* 查询商品列表
* @return
*/
public List<ItemsCustome> selectItemsList(ItemsVo itemsVo) throws Exception;
}
2.3.2、实现service接口
/**
* service接口实现类
* @author guai
*
*/
public class ItemsServiceImpl implements ItemsService {
private ItemsMapperCustome itemsCustome;
@Override
public List<ItemsCustome> selectItemsList(ItemsVo itemsVo) throws Exception {
// TODO Auto-generated method stub
//通过mapper接口获取数据
return itemsCustome.selectItemsList(itemsVo);
}
}
2.3.3、在spring中配置service
创建applicationContext_service.xml并配置service
<!-- 配置商品管理的service -->
<bean id="itemsService" class="com.shuai.service.ItemsService"></bean>
2.4、事务控制(applicationContext-transaction.xml)
使用spring声明式配置方法配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd ">
<!-- 事务管理器
对mybatis操作数据库事务控制,spring使用jdbc的事务控制
-->
<bean id="transcationManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 配置数据源
在applicationContext-dao中的sataSource
-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 配置 通知 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<!-- 传播行为 即需要事务管理的
propagation:传播特性
PROPAGATION_REQUIRED: 如果存在一个事务,则支持当前事务。如果没有事务则开启;
PROPAGATION_SUPPORTS: 如果存在一个事务,支持当前事务。如果没有事务,则非事务的执行;
PROPAGATION_MANDATORY: 如果已经存在一个事务,支持当前事务。如果没有一个活动的事务,则抛出异常;
PROPAGATION_REQUIRES_NEW: 总是开启一个新的事务。如果一个事务已经存在,则将这个存在的事务挂起;
PROPAGATION_NOT_SUPPORTED: 总是非事务地执行,并挂起任何存在的事务;
PROPAGATION_NEVER: 总是非事务地执行,如果存在一个活动事务,则抛出异常;
PROPAGATION_NESTED:如果一个活动的事务存在,则运行在一个嵌套的事务中. 如果没有活动事务, 则按TransactionDefinition.PROPAGATION_REQUIRED 属性执行。
REQUIRED 必需事务管理
SUPPRORTS 支持事务管理 没有就算了
name:过滤service中的方法名
-->
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="insert*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="select*" propagation="SUPPORTS" read-only="false"/>
</tx:attributes>
</tx:advice>
<!-- aop 调用事务
-->
<aop:config>
<!-- 配置切点 --需要加强的方法 -->
<aop:advisor advice-ref="txAdvice" pointcut="execution(*com.shuai.service.impl.*.*(..))"/>
</aop:config>
</beans>
2.4、整合springmvc
创建springmvc.xml文件,配置处理器、映射器、适配器,视图解析器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd ">
<!-- 扫描handller controller 使用该bean可以不在配置映射器 -->
<context:component-scan base-package="com.shuai.controller"></context:component-scan>
<!-- 注解驱动 可以代替适配器-->
<mvc:annotation-driven></mvc:annotation-driven>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
2.5、在web.xml中配置前端控制器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>SpringMvcAndMybatis</display-name>
<!-- 配置前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--配置要扫描的springmvc配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/springmvc.xml</param-value>
</init-param>
</servlet>
<!-- <url-pattern>:指定相对于Servlet的URL的路径。该路径相对于web应用程序上下文的根路径。<servlet-mapping>将URL模式映射到某个Servlet,即该Servlet处理的URL。! -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
2.6、开发Controller(就是Handller)
package com.shuai.controller;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.shuai.pojo.Items;
import com.shuai.pojo.ItemsCustome;
import com.shuai.service.ItemsService;
/**
* 商品的controller
* @author guai
*
*/
//标识这是一个控制器
@Controller
public class ItemsController{
@Autowired
private ItemsService itemsService;
//商品查询
//@RequestMapping实现对queryItems方法和url进行映射
@RequestMapping("/selectItems")
public ModelAndView queryItems()throws Exception{
List<ItemsCustome> itemsList=new ArrayList<ItemsCustome>();
itemsList=itemsService.selectItemsList(null);
//返回ModelAndView
ModelAndView modelAndView=new ModelAndView();
//相当与request的setAttribut
modelAndView.addObject("itemsList",itemsList);
//指定视图
modelAndView.setViewName("/items/itemsList");
return modelAndView;
}
//可以定以其它方法
}
2.7、编写jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<table>
<tr>
<td>商品id</td>
<td>商品名称</td>
<td>商品图片</td>
<td>商品生产日期</td>
<td>商品描述</td>
<td>操作</td>
</tr>
<c:forEach items="${itemsList}" var="item">
<tr>
<td> ${item.id}</td>
<td> ${item.name}</td>
<td> ${item.pic}</td>
<td><fmt:formatDate value="${item.createtime}" pattern="yyyy-MM-dd"/></td>
<td> ${item.detail}</td>
<td><a href="${pageContext.request.contextPath}/items/selectItemsById.action?id=${item.id}">修改</a></td>
</tr>
</c:forEach>
</table>
</body>
</html>
2.8、加载spring容器
将mapper、service、controller加载到spring容器中。
建议使用通配符加载上面的配置文件。在web.xml中,添加spring容器监听,加载spring容器。
<!-- 加载spring容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/CLASSES/springmvc/application-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.spri
ngframework.web.context.ContextLoaderListener</listener-class>
</listener>
2.9、测试:
3、商品修改功能开发
3.1、需求
操作流程:
1、进入商品列表页面
2、点击修改,进入商品修改页面,页面中显示要修改的信息。(从数据库中查询),根据商品id查询商品信息。
3、在商品修改页面,修改商品信息
3.2、 开发mapper
根据id查询商品信息
根据id更新Items表的数据
可直接使用逆向工程生成的代码
3.3 、开发service
接口功能:
根据id查询商品信息
修改商品信息
在service接口中定义方法:
/**
* 根据用户修改商品
* @param id
* @return
* @throws Exception
*/
public ItemsCustome selectItemsById(Integer id) throws Exception;
/**
* 修改商品信息
* @param itemsCustome 根据itemsCustome中的id修改
* @throws Exception
*/
public void updateItems(ItemsCustome itemsCustome) throws Exception;
接口实现方法:
注意要先注入ItemsMapper
@Autowired
private ItemsMapper itemsMapper;
@Override
public ItemsCustome selectItemsById(Integer id) throws Exception {
// TODO Auto-generated method stub
if(id==null) {
return null;
}
ItemsCustome itemsCustome=new ItemsCustome();
//此处的itemsMapper为逆向生成的mapper接口
Items items=itemsMapper.selectByPrimaryKey(id);
//将items中属性值复制到itemsCustome中
BeanUtils.copyProperties(items, itemsCustome);
return itemsCustome;
}
@Override
public void updateItems(ItemsCustome itemsCustome) throws Exception {
// TODO Auto-generated method stub
//根据id修改用户信息
itemsMapper.updateByPrimaryKey(itemsCustome);
}
3.4、开发controller
方法:商品信息修改页面的显示
商品信息修改提交方法
//商品信息修改页面的展示
根据id查询商品的controller方法:
@RequestMapping(value="/selectItemsById")
public ModelAndView selectItemsById(Model model)throws Exception{
ModelAndView modelAndView=new ModelAndView();
//调用service根据用户id查询商品信息 此处默认设置参数为1 后面参数绑定部分会将这里改为从jsp页面传递过来的参数
ItemsCustome itemsCustome=itemsService.selectItemsById(1);
//将商品信息放到model
modelAndView.addObject("itemsCustome", itemsCustome);
//商品修改页面
modelAndView.setViewName("/items/selectItemsById");
return modelAndView;
}
修改商品的方法
//商品信息修改的提交
@RequestMapping("/submitEdit")
public String submitEdit()throws Exception{
//只跳转,暂时不做修改操作,后面会做
//重定向到商品商品列表页面
return "redirect:selectItems.action";
}
3.5、添加修改商品的页面:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="/items/submitEdit?itemsCustome=" method="post">
<table>
<tr>
<td>商品id</td>
<td>商品名称</td>
<td>商品图片</td>
<td>商品生产日期</td>
<td>商品描述</td>
</tr>
<tr>
<td><input type="text" name="id" value="${itemsCustome.id}"
readonly="readonly"> ${item.id}</td>
<td><input type="text" name="name" value="${itemsCustome.name}"></td>
<td><input type="text" name="pic" value="${itemsCustome.pic}"></td>
<td><input type="text" name="createtime"
value="<fmt:formatDate value="${itemsCustome.createtime}" pattern="yyyy-MM-dd"/>">
<td><input type="text" name="price" value="${itemsCustome.price}"></td>
</tr>
<tr>
<td><input type="submit" value="提交"></td>
</tr>
</table>
</form>
</body>
</html>
3.6、
运行结果:
商品列表页面
商品修改页面
4、@RequestMapping
作用:定义controller方法对应的url,进行处理器映射使用
1)用在controller前来窄化请求路径
2)可以限制http请求方式
5、controller方法的返回值
1)返回ModelAndView
2)返回Sting
如果方法返回的为String,表示返回逻辑视图名
真正的视图(jsp路径)=前缀 + 逻辑视图名 + 后缀
//商品信息修改页面的展示
//method: 设置html请求方式 属性类型为数组可以设置多个
@RequestMapping(value="/selectItemsById",method= {RequestMethod.GET,RequestMethod.POST})
public String selectItemsById(Model model)throws Exception{
//调用service根据用户id查询商品信息
ItemsCustome itemsCustome=itemsService.selectItemsById(1);
//将商品信息放到model
model.addAttribute("itemsCustome", itemsCustome);
return "/items/selectItemsById";
}
2.1)redirect 重定向
商品修改提交后,重定向到商品查询列表。
redirect特点:浏览器地址栏中的url会变化,修改提交的request数据无法传到定向的地址(request无法共享)
2.2)forward 页面转发
特点:url地址栏不变,request可以共享
3)返回void
6、参数绑定
6.1、springmvc参数绑定过程
从客户端请求key/value数据,经过参数绑定,将key/value数据绑定到controller方法的形参上。
springmvc中,接收页面提交的数据是通过方法形参来接受。而不是controller类定义成员变量接收。
6.2、参数绑定默认类型
HttpServletRequest
HttpServletSResponse
Model/ModelMap
HttpSession
还支持一些简单类型
例如:这里将上面根据id搜索的方法中的参数改为从jsp页面传递过来的参数
//商品信息修改页面的展示
//method: 设置html请求方式 属性类型为数组可以设置多个
@RequestMapping(value="/selectItemsById",method= {RequestMethod.GET,RequestMethod.POST})
public String selectItemsById(Model model,Integer id)throws Exception{
//调用service根据用户id查询商品信息
ItemsCustome itemsCustome=itemsService.selectItemsById(id);
//将商品信息放到model
model.addAttribute("itemsCustome", itemsCustome);
return "/items/editItems";
}
测试:
注意:当使用上面的方法传递参数时参数名称与jsp中通过url传递的参数名称要一致
即:都要为id
如不一致请使用下面的方法:
6.3、 @RequestParam 的使用
当使用@RequestParam时参数名可以不一致
例:
6.3.1、@RequestParam(value=“id”) Integer item中的属性
value:与jsp中url传递的参数名需一致
其它:required=true 该参数不能为空 即通过url调用该参数时必须传递此参数
defaultValue=“——”为参数设置默认值
例;
6.4、绑定popjo
在修改商品信息时需要将jsp页面中的数据收集并作为参数传递到方法中 方法中的参数为ItemsCustome类型;
//商品信息修改的提交
@RequestMapping("/submitEdit")
public String submitEdit(ItemsCustome itemsCustome)throws Exception{
//调用service例更新商品信息的方法
itemsService.updateItems(itemsCustome);
return "redirect:selectItems.action";
}
注意:输入框的name属性值要与pojo属性名称一致才可以将参数传递过去,(处理器适配器会将输入框中的值自动映射到类的属性中,但名称一定要一致)
如下:
6.4.1、调试时发现商品信息里的中文出现乱码
此时需要在web.xml中配置一个编码过滤器
<!-- 配置post过滤器 -->
<filter>
<filter-name>CharaterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharaterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
FF经测试乱码已修复
注意如出现get乱码解决方法
6.5、自定义参数绑定实现日期类型绑定
当controller中方法的参数为pojo时,如果pojo中有日期类型,需要自定义参数绑定
将请求日期字符串转成日期类型。要转换日期类型要与pojo中属性的类型保持一致。
方法:需要在处理器适配器中注入自定义的参数绑定组件。
第一步在spring.xml中配置自定义参数绑定的并绑定到 注解驱动中去
<!-- 注解驱动 可以代替适配器-->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
<!-- 自定义参数绑定 -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<list>
<!-- 日期类型转换 -->
<bean class="com.shuai.controller.controller.DateConverter"/>
</list>
</property>
</bean>
第二步自定义一个日期转换的类:
/**
* 自定义日期转换器 转换器类需要实现Converter接口,该接口为泛型接口
*
* @author guai
*
*/
public class DateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
// TODO Auto-generated method stub
// 将日期串转化为日期类型
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//转换成功则返回结果 不成功返回空值
try {
return simpleDateFormat.parse(source);
} catch (Exception e) {
// TODO: handle exception
return null;
}
}
}
测试发现createTime已正常获取参数:
我们修改一下试试 哭唧唧
撒花
7、springMvc与struts2的区别
7.1、springMvc基于方法开发的,struts2基于类开发
1)springMvc将url和controller方法映射,映射成功后springMvc生成一个Handller对象,对象中只包括了一个method
方法执行结束,形参销毁。
springmvc的controller开发类似service开发。
2)springMvc可以进行单例开发,因为是基于方法开发的,当多线程访问时每个方法中的参数都有自己的内存空间,互不干扰。
Struts通过类的成员变量接受参数,无法使用单例,因为在多线程时访问时成员变量是共享的。
3)struts2速度慢在于使用了struts2标签。