一、SpringMvc的数据绑定流程
在SpringMvc中会将来自web页面的请求和响应数据与controller中对应的处理方法的入参进行绑定,即数据绑定。
流程如下:
1. SpringMvc主框架将 ServletRequest 对象及目标方法的入参实例传递给 WebDataBinderFactory 实例,以创建 DataBinder 实例对象。
2. DataBinder 对象调用装配在SpringMvc上下文中的 ConversionService组件进行数据类型转换,数据格式化工作,将Servlet 中的请求信息填充到入参对象中。
3. 调用 Validator 组件对已经绑定了请求消息的入参对象进行数据合法性校验,并最终生成数据绑定结果 BindingData 对象。
4. SpringMvc抽取 BindingResult 中的入参对象和校验错误对象,将它们赋给处理方法的相应入参。
数据转换:
SpringMvc上下文中内建了很多转换器,可以完成大多数Java类型转换工作。但是如果要转换成我们自定义的类型时,那么我们就要自定义类型转换器,并将其加入到conversionService中,conversionService中包含了很多SpringMvc内建的转换器。
ConversionService是SpringMvc类型转换体系的核心接口,可以利用 ConversionServiceFactoryBean 在Spring的IOC容器中定义一个ConversionService,Spring将自动识别出IOC容器中的ConversionService,并在bean属性配置及SpringMvc处理方法入参绑定等场合使用它进行数据转换。
二、springmvc自定义数据转换器
Spring支持三种类型的转换器接口,实现任意一个转换器接口都可以作为自定义转换器注册ConversionServiceFactoryBean中:
1. Converter<S,T>: 将S类型的对象转为T类型对象
2. ConverterFactory: 将相同系列多个"同质" Converter 封装在仪器,如果希望将一种类型的对象转换为一种类型及其子类的对象(例如将String转化为Number及Number的子类)
3. GenericConverter: 会根据源类对象与目标类对象所在的宿主类中的上下文信息进行类型转换。
<mvc:annotation-driven conversion-service="conversionService"/>会将自定义的ConversionService注册到SpringMvc的上下文中去。
使用Converter<S,T>转换器接口的实例步骤: 约定字符串类型转换为POJO对象
1、jsp页面:
<form action="${pageContext.request.contextPath }/convetUser" method="post" >
约定字符串格式(id,username,password,department_id):<input type="text" name="user"/> <br/>
<input type="submit" value="保存"> <br/>
</form>
这里input标签的name的值:必须是模型对象User的类名的第一个字母变小写:user
2、编写自定义数据转换器类:实现Converter<S,T>转换器接口
public class StringConvetUser implements Converter<String, User> {
@Autowired
private DepartmentService departmentService;
@Override
public User convert(String source) {
//id,username,password,department_id
if(source != null) {
String[] arr = source.split(",");
User user = new User();
user.setId(Integer.parseInt(arr[0]));
user.setUsername(arr[1]);
user.setPassword(arr[2]);
Department department = departmentService.get(Integer.parseInt(arr[3]));
user.setDepartment(department);
return user; //完成类型转换,返回user对象
}
return null;
}
}
3、在springmvc.xml配置文件中配置转换器类(并注册进容器)
关于FormattingConversionServiceFactoryBean与ConversionServiceFactoryBean的比较:
ConversionServiceFactoryBean:只有数据转换功能;
FormattingConversionServiceFactoryBean:具有数据转换和数据格式化功能;可以注册自定义的转换器,又可以注册自定义的注解驱动器逻辑。
<!-- 简写形式: 默认会帮我们注册默认处理请求,参数和返回值的类-->
<mvc:annotation-driven conversion-service="conversionService"/>
<bean id="" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/view/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 配置自定义的数据转换器,并注入到springmvc容器中-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="cn.jq.sshweb.web.StringConvetUser"></bean>
</set>
</property>
</bean>
4、编写Controller的处理方法
@RequestMapping(value = "/convetUser")
public String convetUser() {
return "user-convet";
}
@RequestMapping(value = "/convetUser", method = RequestMethod.POST)
public String convetUser(User user) {
System.out.println("string类型转换成User对象:"+ user);
userService.add(user);
return "redirect: /sshweb/users";
}
测试结果: