一. 数据流程绑定分析
前端表单传递过来的数据为什么能够自动的封装成实体类的对象?为什么能够进行自动的类型转换?
数据绑定流程:
①:SpringMVC框架将ServletRequest对象及目标方法的入参实例传递给WebDataBinderFactory实例,以便创建DataBinder对象
②:DataBinder调用装配在SpringMVC上下文中的ConversionService组件进行数据类型转换和数据类型格式化操作,将ServletRequest请求参数绑定到对应目标方法的入参对象中
③:调用Validator组件对已经绑定到了目标方法入参对象进行数据合法性的校验,并最终形成数据绑定的结果到BindingData对象
④:SpringMVC将数据校验、格式化、转换的错误信息封装到BindingResult对象中
二. 自定义类型转换器
SpringMVC上下文中内建了很多的类型转换器,可以完成绝大多数的Java类型的转换工作。这些不是我们关注的目标,我们的目标是自定义类型转换器。ConversionService是类型转换核心的接口,可以利用ConversionServiceFactoryBean在SpringIOC容器中定义一个ConversionService,Spring将自动的识别IOC容器中的ConversionService,并在bean属性配置及SpringMVC处理方法入参绑定等场合使用这个ConversionService进行数据转换。所以可以通过ConversionServiceFactoryBean的converters属性注册自定义类型转换器。
Spring支持的类型转换器:Spring中定义了三种类型转换的接口,实现任意一个接口都可以作为自定义的类型转换器,自定义的类型转换器注册到ConversionServiceFactoryBean中,类型转换器就生效了,哪三种呢?
- Converter : 表示将S类型转换成T类型
- ConverterFactory
- GenericConverter
范例:将字符串转换成EMP对象 比如字符串“YYY-yyy@163.com-1-4”
①:编写页面
<form action="${pageContext.request.contextPath}/insertemp" method="post">
<input type="text" name="emp" value="YYY-yyy@163.com-1-4"><button>Submit</button>
</form>
②:编写请求处理器的目标方法
/**
* 新增
* @return
*/
@RequestMapping(value="insertemp",method=RequestMethod.POST)
public String testConverter(@RequestParam("emp")Emp emp) {
this.empManagerSerivce.insertEmp(emp);
return "redirect:/emps";
}
③:编写自定义的类型转换器
public class EmpConverter implements Converter<String, Emp> {
@Override
public Emp convert(String arg0) {
Emp emp = new Emp();
//YYY-yyy@163.com-1-4
String properties[] = arg0.split("-");
emp.setEmpName(properties[0]);
emp.setEmpMail(properties[1]);
emp.setEmpGender(Integer.parseInt(properties[2]));
emp.setDeptId(Integer.parseInt(properties[3]));
return emp;
}
}
④:配置
<!--
mvc:annotation-driven : 是万能的注解驱动
conversion-service : 配置SpringMVC上下文中中的类型转换器
- 不配置:使用默认的
- 配置:默认的+配置的
-->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
<bean id="empConverter" class="com.wanbangee.util.EmpConverter"></bean>
<!-- 配置ConversionFactoryBean 的 converters 属性 -->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<ref bean="empConverter"/>
</set>
</property>
</bean>
三. annotation-driven配置
如果在Spring的配置文件中配置annotation-driven配置,SpringMVC的上下文中会自动的注册RequestMappingHandlerMapping,RequestMappingHandlerAdpater,ExceptionHandlerExceptionResolver这个三个bean,另外的话还提供下列支持:
- 支持使用ConversionService对参数进行类型转换
- 支持使用@NumberFormat,@DateFormat完成数据格式化
- 支持使用@Valid注解对请求参数惊醒JSR303校验
- 支持使用@RequestBody和@ResponseBody注解