|  | 本文参考《精通Spring:JavaWeb开发技术详解》,作者:孙卫琴,清华大学出版社出版 
 Spring框架本身也提供了一套数据验证机制。运用这套验证机制包括以下两个步骤:
 (1)创建实现org.springframework.validation.Validator接口的数据验证类。在本范例中为PersonValidator类。
 (2)在Spring MVC框架中创建数据验证类的对象并通过它进行数据验证。
 
 1. 实现Spring的Validator接口Spring API提供了一个数据验证接口:org.springframework.validation.Validator接口。以下例程1的PersonValidator类实现了Validator接口。PersonValidator类会验证Person类的userName属性和password属性。
 
 例程1 PersonValidator.java
 
 
 | package mypack; import org.springframework.validation.Errors;
 import org.springframework.validation.ValidationUtils;
 import org.springframework.validation.Validator;
 
 public class PersonValidator implements Validator{
 
 public boolean supports(Class<?> clazz) {
 returnPerson.class.equals(clazz);
 }
 
 public voidvalidate(Object obj, Errors errors) {
 
 ValidationUtils.rejectIfEmpty(errors, "userName",
 "person.no.username.error");
 
 ValidationUtils.rejectIfEmptyOrWhitespace(errors, "password",
 "person.no.password.error");
 
 Personperson=(Person) obj;
 if(person.getPassword() != null  && person.getPassword()!=""
 && person.getPassword().length()!=6){
 errors.rejectValue("password",
 "person.tooshort.password.error");
 }
 }
 }
 | 
 PersonValidator类实现了Validator接口的以下方法:
 (1)supports()方法:指定PersonValidator类所验证的数据类型。
 (2)validate()方法:进行数据验证。
 
 PersonValidator类的validate()方法首先利用ValidationUtils类来验证Person对象的userName属性和password属性。ValidationUtils类是Spring API提供的用于数据验证的实用类,它有以下常用的静态方法:
 (1)rejectIfEmpty():如果待验证数据为空,就生成错误消息。验证逻辑等同于Hibernate Validator的@NotEmpty注解。
 (2)rejectIfEmptyOrWhitespace():如果待验证数据去除两端空格后为空,就生成错误消息。验证逻辑等同于Hibernate Validator的@NotBlank注解。
 
 ValidationUtils类的rejectIfEmpty()和rejectIfEmptyOrWhitespace()都有一些重载方法。以下是rejectIfEmpty()的常用重载方法:
 (1)rejectIfEmpty(Errors errors, String field, String errorCode) :参数errorCode指定错误消息编号。
 (2)rejectIfEmpty(Errors errors, String field, String errorCode, StringdefaultMessage) :参数defaultMessage):参数defaultMessage指定默认的错误消息文本。
 
 2. 用数据验证类进行数据验证对于PersonValidator对象,到底由谁来创建并管理它的生命周期,并且如何在控制器类中使用它呢?创建以及使用PersonValidator对象有三种方式。
 2.1把PersonValidator对象和PersonController的当前DataBinder对象绑定在PersonController控制器类中,以下initBinder()方法会把PersonBinder对象加入到当前的DataBinder对象中:
 
 | @InitBinder public void initBinder(DataBinder binder) {
 binder.setValidator(new PersonValidator());
 }
 | 
 org.springframework.validation.DataBinder类是Spring框架提供的用来存放数据验证对象的容器类。以上initBinder()方法用@InitBinder注解标识,Spring MVC框架在每次调用PersonController的请求处理方法之前,先调用initBinder()方法,创建PersonValidator对象,并把它与当前的DataBinder对象绑定。这个PersonValidator对象专门为PersonController的请求处理方法进行数据验证。
 
 PersonController的请求处理方法可以通过JSR-303的@Valid注解来声明对person参数进行数据验证:
 
 
 | public String greet(   @Valid @ModelAttribute("personbean")Person person, BindingResult bindingResult,Model model){……}
 | 
 以上@Valid注解声明要对person参数进行验证,Spring MVC框架就会利用与当前DataBinder对象绑定的PersonValidator进行相应的数据验证。
 
 2.2注册PersonValidator Bean组件,并把它设为全局的数据验证类在Spring MVC的配置文件中配置PersonValidator类的代码如下:
 
 | <bean id="personValidator" class="mypack.PersonValidator"/> <mvc:annotation-drivenvalidator="personValidator" />
 | 
 以上<bean>元素向Spring MVC框架注册了PersonValidator Bean组件,<mvc:annotation-driven>的validator属性指向这个PersonValidator Bean组件。这样,当控制器类需要对Person类型的数据进行验证时,Spring MVC框架就会利用PersonValidator对象来完成实际的数据验证功能。按照这种方式配置的PersonValidator对象的数据验证范围是整个Web应用。
 
 PersonController的请求处理方法可以通过JSR-303的@Valid注解来声明对person参数进行数据验证:
 
 
 | public String greet(  @Valid @ModelAttribute("personbean")Person person,
 BindingResult bindingResult,Model model){……}
 | 
 以上@Valid注解声明要对person参数进行验证,Spring MVC框架就会利用全局范围内的PersonValidator进行相应的数据验证。
 
 值得注意的是,PersonValidator并没有提供通用的数据验证功能,只能对Person类型的数据进行验证,把它作为全局的数据验证类,实际上并不值得推荐。
 
 2.3注册PersonValidator Bean组件,PersonController通过@Resource注解访问它在Spring MVC的配置文件中配置PersonValidator类的代码如下:
 
 | <bean id="personValidator" class="mypack.PersonValidator"/> | 
 以上<bean>元素向Spring MVC框架注册了PersonValidator Bean组件,Spring MVC框架会负责管理PersonValidator对象的生命周期。
 
 在PersonController类中,通过来自javax.annotation包的@Resource注解访问由Spring MVC框架提供的PersonValidator对象:
 
 
 | @Controller public class PersonController {
 @Resource
 //由Spring MVC框架提供PersonValidator对象
 private PersonValidator personValidator;
 @RequestMapping(value = {"/input","/"},method =RequestMethod.GET)
 
 public String init(Model model) {
 model.addAttribute("personbean",new Person());
 return"hello";
 }
 
 @RequestMapping(value = "/sayHello", method =RequestMethod.POST)
 public String greet( @ModelAttribute("personbean")Person person,
 BindingResult bindingResult,Model model) {
 
 personValidator.validate(person,bindingResult);
 
 if(bindingResult.hasErrors()){
 return"hello";
 }
 ……
 }
 }
 | 
 PersonController类的personValidator成员变量用@Resource注解标识,意味着PersonController类无需创建PersonValidator对象,Spring MVC框架会把PersonValidator Bean组件赋值给personValidator成员变量。
 
 
 程序猿的技术大观园:www.javathinker.net
 |  |