数据转换、格式化、校验
数据绑定机理
数据类型转换
低版本的Spring 只支持标准的PropertyEditor类型体系,不过PropertyEditor存在以下缺陷:
只能用于字符串和Java对象的转换,不适用于任意两个Java类型之间的转换;
对源对象及目标对象所在的上下文信息(如注解、所在宿主类的结构等)不敏感,在类型转换时不能利用这些上下文信息实施高级转换逻辑。
有鉴于此,Spring 3.0在核心模型中添加了一个通用的类型转换模块,ConversionService是Spring类型转换体系的核心接口。
Spring 3.0同时支持PropertyEditor和ConversionService 进行类型转换,在Bean配置、Spring MVC处理方法入参绑定中使用类型转换体系进行工作。
对于简单的类型转换,依然建议使用PropertyEditor。按照PropertyEditor的协议,会自动查找Bean类相同类包是否存在<BeanName>Editor.class,如果存在会使用它作为Bean的编辑器。
<bean id="expireManager"
class="com.book.core.cache.expire.SimpleCacheLogicExpireManager">
<property name="cacheSpaceList">
<list>
<value>comBookSpace:com/comBook/**</value>
<value>bookSpace:com/book/**:100</value>
<value>companySpace:com/company/**</value>
</list>
</property>
</bean>
基于ConversionService体系,定义自定义的类型转换器
定义自定义转换器:
注册自定义转换器:
<mvc:annotation-driven conversion-service="conversionService"/>
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.baobaotao.domain.StringToUserConverter"/>
</list>
</property>
</bean>
使用支持格式化的转换器
<mvc:annotation-driven conversion-service="conversionService"/>
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="com.baobaotao.domain.StringToUserConverter"/>
</list>
</property>
</bean>
值得注意的是,<mvc:annotation-driven/>标签内部默认创建的ConversionService实例就是一个FormattingConversionServiceFactoryBean,自动支持如下的格式化注解:
@NumberFormatter:用于数字类型对象的格式化。
@CurrencyFormatter:用于货币类型对象的格式化。
@PercentFormatter:用于百分数数字类型对象的格式化。
数据校验框架
Spring 3.0拥有自己独立的数据校验框架,同时支持JSR 303标准的校验框架。Spring 的DataBinder在进行数据绑定时,可同时调用校验框架完成数据校验工作。在Spring MVC中,则可直接通过注解驱动的方式进行数据校验。
Spring的org.springframework.validation是校验框架所在的包。JSR 303是Java为Bean数据合法性校验所提供的标准框架,它已经包含在Java EE 6.0中。JSR 303通过在Bean属性上标注类似于@NotNull、@Max等标准的注解指定校验规则,并通过标准的验证接口对Bean进行验证。你可以通过http://jcp.org/en/jsr/detail?id=303了解JSR 303的详细内容。
<mvc:annotation-driven/>会默认装配好一个LocalValidatorFactoryBean,通过在处理方法的入参上标注@Valid注解即可让Spring MVC在完成数据绑定后执行数据校验的工作。
public class User {
@Pattern(regexp="w{4,30}")
private String userName;
@Length(min=2,max=100)
private String realName;
@Past @DateTimeFormat(pattern="yyyy-MM-dd")
private Date birthday;
@DecimalMin(value="1000.00")@DecimalMax(value="100000.00") @NumberFormat(pattern="#,###.##")
private long salary;
}
注意:Spring本身没有提供JSR 303的实现,所以必须将JSR 303的实现者(如Hibernate Validator)的jar文件放到类路径下,Spring将自动加载并装配好JSR 303的实现者。
如何使用注解驱动的校验
在已经标注了JSR 303注解的表单/命令对象前标注一个@Valid,Spring MVC框架在将请求数据绑定到该入参对象后,就会调用校验框架根据注解声明的校验规则实施校验。
@Controller
@RequestMapping("/user")
public class UserController{
@RequestMapping(value = "/handle91")
public String handle91(@Valid User user,
BindingResult bindingResult){
if(bindingResult.hasErrors()){
return "/user/register3";
}else{
return "/user/showUser";
}
}
}
使用校验功能时,处理方法要如何签名??
Spring MVC是通过对处理方法签名的规约来保存校验结果的:
前一个表单/命令对象的校验结果保存在其后的入参中,这个保存校
验结果的入参必须是BindingResult或Errors类型,这两个类都位于
org.springframework.validation包中。
校验错误信息存放在什么地方??
1、Spring MVC将HttpServletRequest对象数据绑定到处理方法的入
参对象中(表单/命令对象);
2、将绑定错误信息、检验错误信息都保存到隐含模型中;
3、本次请求的对应隐含模型数据存放到HttpServletRequest的属性列
表中,暴露给视图对象。
页面如何显示错误信息
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
<title>注册用户</title>
<style>.errorClass{color:red}</style>
</head>
<body>
<form:form modelAttribute="user" action="user/handle91.html">
<form:errors path="*"/>
<table>
<tr>
<td>用户名:</td>
<td>
<form:errors path="userName" cssClass="errorClass"/>
<form:input path="userName" />
</td>
</tr>
…
</table>
</form:form>
</body>
</html>