1 SpringMVC的数据绑定流程
- SpringMVC将ServletRequest对象及目标方法的入参实例传递给WebDataBinderFactory实例,以创建DataBinder实例对象。
- DataBinder调用装配在SpringMVC上下文中ConversionService组件进行数据类型转换、数据格式化工作。将Servlet中的请求信息填充到入参对象中。
- 调用Validator组件对已经绑定了请求信息的入参对象进行数据合法性校验,并最终生成数据绑定结果BindingData对象。
- SpringMVC抽取BindingResult中的入参对象和校验错误对象,将它们赋给处理方法的响应入参。
- SpringMVC通过反射机制对目标处理方法进行解析,将请求消息绑定到处理方法的入参中。数据绑定的核心部件是DataBinder,运行机制如下:
2 数据转换
- SpringMVC上下文中内建了很多转换器,可以完成大多数Java类型的转换工作。
2.1 自定义类型转换器
- ConversionService是Spring类型转换体系的核心接口。
- 可以利用ConversionServiceFactoryBean在Spring的IOC容器中定义一个ConversionService。Spring将自动识别出IOC容器中的ConversionService,并在Bean属性配置及SpringMVC处理方法入参绑定等场合使用它进行数据的转换。
- 可以通过ConversionServiceFactoryBean的converters属性注册自定义的类型转换器。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<a href="${pageContext.request.contextPath}/test?user=adc,123456,1">增加数据</a>
</body>
</html>
package com.sunxiaping.springmvc.domain;
import java.io.Serializable;
public class User implements Serializable {
private String username;
private String password;
private Integer age;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
package com.sunxiaping.springmvc.converters;
import com.sunxiaping.springmvc.domain.User;
import org.springframework.core.convert.converter.Converter;
public class UserConverter implements Converter<String, User> {
@Override
public User convert(String s) {
if (null == s || s.length() == 0) {
return null;
}
String[] split = s.split(",");
User user = new User();
user.setUsername(split[0]);
user.setPassword(split[1]);
user.setAge(Integer.parseInt(split[2]));
return user;
}
}
package com.sunxiaping.springmvc.controller;
import com.sunxiaping.springmvc.domain.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class UserController {
@RequestMapping(value = "/test")
public String test(User user){
System.out.println(user);
return "success";
}
}
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd ">
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.sunxiaping.springmvc"></context:component-scan>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.sunxiaping.springmvc.converters.UserConverter"></bean>
</set>
</property>
</bean>
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
</beans>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
成功啦 <br/>
</body>
</html>
2.2 关于<mvc:annotation-drivern>
- <mvc:annotation-drivern>会自动注册RequestMappingHandlerMapping、RequestMappingHandlerAdapter和ExceptionHandlerExceptionResolver三个Bean。
- 还将提供以下的支持:
- 支持使用ConversionService实例对表单参数进行转换。
- 支持使用@NumberFormat注解和@DateTimeFormat注解完成数据格式化。
- 支持使用@Valid注解对JavaBean实例进行JSR303验证。
- 支持使用@RequestBody和@Res婆娘色Body注解。
2.3 @InitBinder注解
- 由@InitBinder标识的方法,可以对WebDataBinder对象进行初始化。WebDataBinder是DataBinder的子类,用于完成由表单字段到JavaBean属性的绑定。
- @InitBinder方法不能由返回值,它必须声明为void。
- @InitBinder方法的参数通过是WebDataBinder。
@InitBinder
public void initBinder(WebDataBinder webDataBinder){
webDataBinder.setDisallowedFields("roleIds");
}
3 数据格式化