Spring MVC是Spring提供的基于 MVC 设计理念的优秀的Web 框架。Spring3.0 后全面超越 Struts2,成为目前最主流的 MVC 框架。本文介绍一下Spring MVC的数据绑定功能。

一.数据绑定流程
Spring MVC 通过反射机制对目标处理方法进行解析,将请求消息绑定到处理方法的入参中。数据绑定的核心部件是DataBinder,运行机制如下:
1. Spring MVC 主框架将请求数据处理为 ServletRequest 对象
2. Spring MVC 主框架将 ServletRequest 对象及目标方法的入参实例传递给 WebDataBinderFactory 实例,以创建 DataBinder 实例对象
3. DataBinder 调用装配在 Spring MVC 上下文中的ConversionService 组件进行数据类型转换、数据格式化工作。将 Servlet 中的请求信息填充到入参对象中
4. 调用 Validator 组件对已经绑定了请求消息的入参对象进行数据合法性校验,并最终生成数据绑定结果BindingData 对象
5. Spring MVC 抽取 BindingResult 中的入参对象和校验错误对象,将它们赋给处理方法的响应入参

springmvc数据绑定 springmvc的数据绑定_springmvc数据绑定

二.数据类型转换和数据格式化
数据类型转换、数据格式化工作,是DataBinder 调用装配在 Spring MVC 上下文中的ConversionService 组件进行的。ConversionService内建了很多转换器,可完成大多数 Java 类型的转换工作。当然,开发者也可以自定义类型转换器,但是实际上没什么必要,这里就不再赘述。数据类型转换和数据格式化通常是一起发生的,要进行格式化,只需要在目标属性上加一些注解即可,比如@NumberFormat、@DateTimeFormat。

三.@InitBinder
1.由 @InitBinder 标识的方法,可以对 WebDataBinder 对象进行初始化。WebDataBinder 是 DataBinder 的子类,由表单字段到 JavaBean 属性的绑定默认就是WebDataBinder完成的。
2.@InitBinder方法不能有返回值,它必须声明为void。
3.@InitBinder方法的参数通常是是 WebDataBinder。@InitBinder 标识的方法,可以通过WebDataBinder的一些方法,在数据绑定做一些特殊处理,比如设置对某字段不进行赋值,比如将页面中的checkbox多选映射为对象中的集合等。

@InitBinder
public void initBinder(WebDataBinder binder){
    binder.setDisallowedFields("lastName");
}

四.数据验证
1.Spring MVC支持 JSR303 标准的校验框架。JSR 303 是 Java 为 Bean 数据合法性校验提供的标准框架,它已经包含在 JavaEE 6.0 中 。JSR 303 通过在 Bean 属性上标注类似于 @NotNull、@Max等标准的注解指定校验规则,并通过标准的验证接口对 Bean进行验证。Hibernate Validator 是 JSR 303 的一个参考实现,除支持所有标准的校验注解外,它还支持一些自己的扩展注解。
2.Spring MVC 在进行数据绑定时,可同时调用校验框架完成数据校验工作。通过在处理方法的入参前标注 @valid 注解即可让 Spring MVC 在完成数据绑定后执行数据校验的工作。
3.前一个Bean对象的校验结果保存到随后的入参中,需校验的 Bean 对象和其绑定结果对象或错误对象是成对出现的,它们之间不允许声明其他的入参。这个保存校验结果的入参必须是 BindingResult 或Errors 类型,BindingResult 扩展了 Errors 接口。每个属性在数据绑定和数据校验发生错误时,都会生成一个对应的 FieldError 对象。Errors 接口提供了获取错误信息的方法,如 getErrorCount() 或getFieldErrors(String field)等,可以用来返回给请求发起者。 

@RequestMapping(value="/emp", method=RequestMethod.POST)
	public String save(@Valid Employee employee, Errors result, 
			Map<String, Object> map){
		System.out.println("save: " + employee);
		
		if(result.getErrorCount() > 0){
			System.out.println("出错了!");
			
			for(FieldError error:result.getFieldErrors()){
				System.out.println(error.getField() + ":" + error.getDefaultMessage());
			}
			
			return new ErrorVO(error.getDefaultMessage());
		}
		
		employeeDao.save(employee);
		return new SuccessVO("操作成功");
	}

如果在方法中不加BindingResult参数,则验证失败后会抛出异常。那么我们就可以用一个统一的拦截器统一处理验证异常。这样我们就可以将验证失败处理交给框架去做,而不用在业务模块加验证处理方法。
4.Spring MVC 会查看WEB 上下文是否装配了对应的自定义国际化消息,如果没有,则显示默认的错误消息,否则使用自定义国际化消息。当一个属性校验失败后,校验框架会为该属性生成 4 个消息代码,这些代码以校验注解类名为前缀,结合modleAttribute、属性名及属性类型名生成多个对应的消息代码,自定义消息的配置文件可以按此规则配置。
例如 User 类中的 password 属性标准了一个 @Pattern 注解,当该属性值不满足 @Pattern 所定义的规则时, 就会产生以下 4个错误代码:
– Pattern.user.password
– Pattern.password
– Pattern.java.lang.String
– Pattern
5.一些底层操作发生错误,会在隐含模型中创建错误消息。其错误代码前缀说明如下:
– required:必要的参数不存在。如 @RequiredParam(“param1”)标注了一个入参,但是该参数不存在
– typeMismatch:在数据绑定时,发生数据类型不匹配的问题
– methodInvocation:Spring MVC 在调用处理方法时发生了错误

 

五一假期整理此文。