数据绑定的流程
- Spring MVC 主框架将ServletRequest对象及目标方法的入参实例传递给
WebDataBinderFactory
实例,以创
建DataBinder
实例对象。 - DataBinder调用装配在 Spring MVC 上下文中的
ConversionService
组件进行数据类型转换、数据格式化工作。将Servlet中的请求信息填充到入参对象中。 - 调用
Validator
组件对已经绑定了请求消息的入参对象进行数据合法性校验,并最终生成数据绑定结果BindingData
对象。 - Spring MVC 抽取
BindingResult
中的入参对象和校验错误对象,将它们赋给处理方法的响应入参。
Spring MVC 通过反射机制对目标处理方法进行解析,将请求消息绑定到处理方法的入参中。数据绑定的核心部件是DataBinder,运行机制如下:
这三个重要的是组件都在binder对象中存储:
自定义类型转换器(了解,较少用)
需求:在输入界面把字符串转换成一个employee对象。
定义类型转换器
首先,这个类型转换器需要实现Converter接口,示例代码如下:
@Component
public class EmployeeConverter implements Converter<String, Employee> {
@Override
public Employee convert(String source) {
if (source != null) {
String[] vals = source.split("-");
// GG-gg@qq.com-0-105
if (vals != null && vals.length == 4) {
String lastName = vals[0];
String email = vals[1];
Integer gender = Integer.valueOf(vals[2]);
Department department = new Department();
department.setId(Integer.valueOf(vals[3]));
Employee employee = new Employee(null, lastName, email, gender, department);
System.out.println(source + "--conventer--" + employee);
return employee;
}
}
return null;
}
}
- 这里,要把这个转换器用@Component修饰,标识他是一个bean。
- 接口中,要声明好它的转换方向,然后实现convert方法。
配置ConversionService
在springmvc.xml中,配置ConversionService,以及我们自定义的转换器,增加如下代码:
<mvc:annotation-driven
conversion-service="conversionService"></mvc:annotation-driven>
<!-- 配置 ConversionService -->
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<ref bean="employeeConverter" />
</set>
</property>
</bean>
- 要把ConversionService配置成一个Bean,并为其属性
converters
赋值,值就是我们自己编写的自定义转换器(bean名字是类型首字符小写的字符串)。 - 将conversionService这个bean配置到SpringMVC中,即
<mvc:annotation-driven conversion-service="conversionService">
。
Handler目标方法
为了测试这个请求,我们需要一个目标方法来处理这个URL,示例代码如下:
@Controller
public class SpringMVCTest {
@Autowired
private EmployeeDao emlpoyeeDao;
@RequestMapping(value = "testConversionServiceConverter", method = RequestMethod.POST)
public String testConverter(@RequestParam("employee") Employee employee) {
System.out.println("save :" + employee);
emlpoyeeDao.save(employee);
return "redirect:emps";
}
}
配置好这个Controller即可。
前端测试代码
<form action="testConversionServiceConverter" method="POST">
<!-- 格式:lastName-email-gender-department.id 例如: GG-gg@qq.com-0-105 -->
employee:
<input type="text" name="employee">
<input type="submit" value="Submit">
</form>
通过这个输入,可以测试该转换器的有效性。通过调试,发现DataBinder对象中的conversionService多了一个我们自己的转换器,而其他的默认转换器照样有效。