数据绑定
Spring提供的数据绑定功能即自动的提取HttpServletRequest中的请求参数,然后自动的转型之后赋给对应的对象。 简单的说就是处理前端页面传输到后台的数据信息与具体Java类对象信息的绑定; 其中数据绑定工作是Spring的SimpleFormController类帮我们完成,我们只需要做的是为数据绑定提供一个目标对象,这个对象在Spring中被称为Command对象
<bean id="commandController" class=".....controller路径名">
<property name="commandClass" value="...类路径">
</bean>
简单概况两个步骤就是:
1. 在Web请求到达之后,Spring
MVC某个框架类会提取当前Web请求中的所有参数名称,然后遍历它,以获取每个参数的值,最终形成一个拥有所有需绑定的参数名和参数值的集合(Collection)
2. 获得了将绑定到Comand对象的数据来源之后,对这些属性根据目标对象中各个属性域的类型进行数据转换,然后在把数据设置到Command对象上
在这个过程中会用到BeanWrapper实现类,BeanWrapperImpl,它会把Command对象纳入自身管理范围
BeanWrapper beanWrpper = new BeanWrapperImpl(command);
它会帮我们完成参数值与Command对象属性之间的类型差异转换工作,然后就可以顺利的根据参数和属性之间的对应关系进行设置了,对应关系设置:
public class User{
private String userName;
private String passWord;
//省略getter和setter方法
}
前端页面:
<input type="text" name="userName"/>
<input type="text" name="passWord"/>
也就是参数名称必须对应Command对象属性的名称。 从参数获取到转型并绑定到Commad对象,整个流程都是以org.springframework.web.bind.Ser-vletRequestDataBinder的形式封装的;BaseCommandController及其子类将负责调用该类完成整个绑定过程,并返回Command对象;而之后我们就只需要对目标对象进行后继处理就可以了,例如验证。
处理表单提交数据
在Web请求到达之后,SimpleFormController将首先通过方法isForm-Submission(request)判明当前请求是否为表单请求,isFormSubmiss-iono(request)的默认实现如下:
protected boolean isFormSubmisson(HttpServletRequest request){
return "POST".equals(request.getMethod());
}
也就是说,只要是以POST发送的Web请求,SImpleFormController将认为当前Web请求为表单提交。 整个表单提交以isFormSubmission(request)的结果划分为“表单显示阶段”和“表单提交处理阶段”两个逻辑处理阶段;如果该方法返回false则通常表示为初次Web请求,这时进行“表单显示阶段”的工作;否则认为用户已经在表单中编辑完数据,需要处理,启用“处理表单提交阶段”处理逻辑。
表单显示阶段流程分析
1. 创建或者获取表单对应的Backing Object。即对应表单数据绑定的Command对象;formBackingObject()方法默认会通过反射实例化我们为SimpleFormController指定的Commad对象实例,但在更新的时候不是新建,而是初始化;即将要更新的实体的数据加载到表单中的时候
2. 初始化DataBinder。即ServletRequestBinder,前面我们说过该类封装类型转换和参数绑定。
3. 执行数据绑定。这一步只有在bindNewForm设为true的时候才会被触发进行,通常设置用来在要更新数据的时候显示数据库原来的表单数据,其默认值是false,因为通常是不会在表单显示之前执行绑定操作的。
public class FormControllerTest extends SimpleFormController {
public FormControllerTest{
setBindOnNewForm(true);
....
}
}
4.处理表单显示;在这还有最后两步工作
- 如果SimpleFormController的sessionForm属性设置为true的话表示会将绑定后的command对象存入HttpSession,这样在提交表单之后会重新获取该command对象而不是重新生成
- Form BackingObject更多的面向表单中的各个字段,与表单中的属性形成双向绑定关系;但有时会需要目标对象之外的消息,这时就需要refre-nceData()来实现,该方法将返回的模型数据添加到即将返回的ModelAnd-View中。
到此SimpleFormController已经对各类数据进行了绑定并放入某个ModelAnd-View实例,然后进行视图解析完成最后的页面转换。
处理表单的提交阶段
- 获取要提交的目标对象。
用户提交表单之后,我们会判断SimpleCont-roller的sessionForm属性是否为true,然后根据属性来选择是直接从HttpS-ession中获取还是重新生成该目标对象 - 初始化DataBinder,与表单显示阶段步骤相同
- 执行数据绑定/数据验证。
绑定阶段和表单显示阶段是一样的,但是我们可以在onBind()方法中进行拓展,进行属性验证,通常是指定一组Valid-ator实现类 - 处理表单提交。 在这一步还需要进行最后一步的验证; 首先SimpleFormController会进行验证消息的检查看是否存在验证错误。如果没有验证错误,在检查一下当前请求只是FormChangeRequest,就是说,当前Web页面只是进行了一些数据改动,而不是最终提交;这时依然不能处理数据,而是需要将视图重新导向表单的显示页面。不过SimpleFormController提供的重载的submit()方法,可以根据需求来覆写。