1.数据绑定介绍
SpringMVC会根据客户端请求参数的不同,将请求消息中的信息以一定的方式转换并绑定到控制器类的方法参数中,这种请求消息数据与后台方法参数建立连接的过程就是SpringMVC中的数据绑定
步骤如下:
(1)SpringMVC将ServletRequest对象传递给DataBinder
(2)将处理方法的入参对象传递给DataBinder
(3)DataBinder调用ConversionService组件进行数据类型转换,数据格式化等工作,并将ServletRequest对象中的消息填充到参数对象中
(4)调用Validator组件对已经绑定了请求消息数据的参数对象进行数据合法性校验
(5)校验完成后会生成数据绑定结果BindingResult对象,SpringMVC会将BindingResult对象中的内容赋给处理方法的响应参数
2.1绑定默认数据
当前端请求的参数比较简单时,可以在后台方法的形参中直接使用SpringMVC提供的默认参数类型进行数据绑定
参数类型 | 说明 |
HttpServletRequest | 通过request对象获取请求信息 |
HttpServletResponse | 通过response处理响应信息 |
HttpSession | 通过session对象得到session中存储的对象 |
Model/ModelMap | Model是一个接口,ModelMap是一个接口实现,作用是将model数据填充到request域 |
demo:以HttpServletRequest为例
(1)springmvc-config.xml
<!--自定义组件扫描器,指定需要扫描的包-->
<context:component-scan base-package="com.itcast.controller"/>
<!--定义视图解析器-->
<bean id="viewResolver" class=
"org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--设置前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--设置后缀-->
<property name="suffix" value=".jsp"/>
</bean>
(2)在com.itcast.controller包下,创建UserController
@Controller
public class UserController{
@RequestMapping(value="/selectUser")
public String selectUser(HttpServletRequest request){
String id=request.getParameter("id");
System.out.println("id="+id);
return "success";
}
(3)在WEB-INF目录下,创建一个jsp的文件夹,创建success.jsp
(4)访问网址: localhost:8080/day03/selectUser?id=1
2.1绑定简单数据类型
指Java中基本数据类型的绑定,如int,String,Double等
demo:
@RequestMapping(value="/selectUser")
public String selectUser(Integer id){
System.out.println("id="+id);
return "success";
}
有时候前端请求中参数名和后端控制器类方法中的形参名不一致,这就会导致后端无法正确绑定并接收到前端请求的参数,为此SpringMVC提供了@RequestParam注解来进行间接数据绑定
属性 | 说明 |
value | name属性的别名,这里指参数的名字,即入参的请求参数名字,如value="item_id",表示请求参数中名字为item_id的参数的值将传入 |
name | 指定请求头绑定的名称 |
required | 用于指定参数是否必须,默认是true,表示请求中一定要有相应的参数 |
defaultValue | 默认值,表示如果请求中没有同名参数时的默认值 |
demo:
假设请求地址为localhost:8080/day03/selectUser?user_id=1,那么controller中为selectUser
@RequestMapping(value="/selectUser")
public String selectUser(@RequestParam(value="user_id")Integer id){
System.out.println("id="+id);
return "success";
}
2.2绑定POJO类型
demo:用户注册案例
(1)User类,id,username,password
(2)UserController
/*
向用户注册页面跳转
*/
@RequestMapping(value="/toRegister")
public String toRegister(){
return "register";
}
/*
接收用户注册信息
*/
@RequestMapping("/registerUser")
public String registerUser(User user){
String username=user.getUsername();
Integer password=user.getPassword();
System.out.println("username"+username);
System.out.println("password"+password);
return "success";
}
(3)register.jsp中编写用户注册表单,以POST方式提交,在请求时发送一条以"/registerUser"结尾的请求消息
<body>
<form action="${pageContext.request.contextpath}/registerUser"method="post">
用户名:<input type="text" name="username"/><br/>
密码:<input type="text" name="password"/> <br/>
<input type="submit" value="注册"/>
</form>
</body>
(4)localhost:8080/day03/toRegister
2.3绑定包装POJO
(1)Orders类,ordersId,user
(2)OrdersController
/*
向订单查询页面跳转
*/
@RequestMapping(value="/tofindOrdersWithUser")
public String tofindOrdersWithUser(){
return "orders";
}
/*
查询订单和用户信息
*/
@RequestMapping("/findOrdersWithUser")
public String findOrdersWithUser(Orders orders){
Integer orderId=orders.getOrdersId();
String username=user.getUsername();
System.out.println("orderId"+orderId);
System.out.println("username"+username);
return "success";
}
(2)orders.jsp
<body>
<form action="${pageContext.request.contextpath}/findOrdersWithUser"method="post">
订单编号:<input type="text" name="ordersId"/><br/>
所属用户:<input type="text" name="user.username"/> <br/>
<input type="submit" value="查询"/>
</form>
</body>
(3)localhost:8080/day03/tofindOrdersWithUser
3.自定义数据绑定
3.1Converter
自定义Converter类需要实现Converter接口,如下
public interface Converter<S,T>{
T convert(S source);
}
泛型中的S表示源类型,T表示目标类型,而converter(S source)表示接口中的方法
demo:
com.itcast.convert包下创建日期转换类DataConverter,在该类中编写将String类型转换成Data类型的代码
/*
自定义日期转换器
*/
public class DataConverter implements Converter<String,Data>{
//定义日期格式
private String dataPattern="yyyy-MM--dd HH:mm:ss";
@Override
public Data convert(String source){
//格式化日期
SimpleDataFormat sdf=new SimpleDataFormat (dataPattern);
try{
return sdf.parse(source);
}catch(ParseException e){
throw new IllegalArgumentException(
"无效的日期格式,请使用正确的格式:"+dataPattern);
}
}
}
为了让SpringMVC知道并使用这个转换器类,还需要在其配置文件中编写一个id为conversionService的Bean
springmvc-config.xml
<!--自定义组件扫描器,指定需要扫描的包-->
<context:component-scan base-package="com.itcast.controller"/>
<!--定义视图解析器-->
<bean id="viewResolver" class=
"org.springframework.web.servlet.view.InternalResourceViewResolver">
<!--设置前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--设置后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<!--显示的装配自定义类型转换器-->
<mvc:annotation-driven conversion-service="conversionService"/>
<!--自定义类型转换器配置-->
<bean id="conversionService" class=
"org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.itcast.convert.DateConverter"/>
</set>
</property>
</bean>
为了测试转换器类的使用,创建一个日期控制器类DataController,并在类中编写绑定日起数据的方法
DataController
/*
日期控制器类
*/
@Controller
public class DataController{
/*
使用自定义类型数据绑定日期数据
*/
@RequestMapping(value="/customDate")
public String customDate(Date date){
System.out.println("date="+date);
return "success";
}
}
localhost:8080/day03/customDate?date=2019-06-27
3.2Formatter
Formatter 作用和Converter作用相同,但是Formatter 的源类型必须是一个String类型,而Converter可以是任意类型
public interface Formatter<T> extends Printer<T>,Parser<T>{}
/*
使用Formatter自定义日期转换器
*/
public class DataFormatter implements Formatter<Date>{
//定义日期格式
String dataPattern="yyyy-MM--dd HH:mm:ss";
//声明SimpleDataFormat 对象
private SimpleDataFormat simpleDataFormat
@Override
public String print(Date date,Locale locale){
return new SimpleDataFormat().format(date);
}
@Override
public Date parse(String source,Locale locale)throws ParseException{
SimpleDataFormat =new SimpleDataFormat (dataPattern);
return simpleDataFormat.parse(source);
}
}
要使用Formatter自定义的日期转换器,需要在springmvc的 配置文件中进行注册
<!--自定义类型转换器配置-->
<bean id="conversionService" class=
"org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatters">
<set>
<bean class="com.itcast.convert.DateFormatter"/>
</set>
</property>
</bean>
4.复杂数据绑定
4.1绑定数组
(1)user.jsp
(2)UserController,编写批量删除用户的方法
/*
向用户列表页面跳转
*/
@RequestMapping("/toUser")
public String selectUsers(){
return "user";
}
/*
接收批量删除用户的方法
*/
@RequestMapping("/deleteUsers")
public String deleteUsers(Integer[] ids){
if(ids !=null){
for(Integer id:ids){
//使用输出语句模拟已经删除的用户
System.out.println("ids=null");
}
return"success";
}
4.2绑定集合
(1)UserVO.java
(2)UserController
/*
向用户批量修改页面跳转
*/
@RequestMapping("/toUserEdit")
public String toUserEdit(){
return "user_edit";
}
/*
接收批量修改用户的方法
*/
public String editUsers(UserVO userList){
//将所有用户数据封装到集合中
List<User> users=userList.getUsers();
//循环输出所有用户信息
for(User user:users){
//如果接收的用户id不为空,则表示对该用户进行了修改
if(user.getId()!=null){
System.out.println("修改了id为:"+user.getId()+"的用户名为:"+user.getname());
}
}
return "success";
}
(3)user_edit.jsp