SpringMVC使用@Valid注解进行数据验证

我们在做Form表单提交的时候,只在前端做数据校验是不够安全的,所以有时候我们需要在后端同样做数据的校验。好在SpringMVC在后台验证给我们提供了一个比较好的支持。那就是使用Valid接口的实现类做数据校验。在这之前我们先做一下准备的工作。

SpringMVC使用@Valid注解进行数据验证

添加相关的Maven依赖

我们先把需要的jar包添加进来。

[html] view plain copy

 
  1. <dependency>
  2.     <groupId>javax.validation</groupId>
  3.     <artifactId>validation-api</artifactId>
  4.     <version>1.1.0.Final</version>
  5. </dependency>
  6. <dependency>
  7.     <groupId>org.apache.bval</groupId>
  8.     <artifactId>bval-jsr303</artifactId>
  9.     <version>0.5</version>
  10. </dependency>

实现Validator接口

接下来的第一 步我们需要写一个类来实现Validator接口。在这个类里我们需要定义它支持校验的JavaBean,实现validate方法,用来进行相关的校验。具体的实现类如下:

[java] view plain copy

 
  1. package com.zkn.learnspringmvc.validtor;
  2. import com.zkn.learnspringmvc.scope.PersonScope;
  3. import org.springframework.util.StringUtils;
  4. import org.springframework.validation.Errors;
  5. import org.springframework.validation.ValidationUtils;
  6. import org.springframework.validation.Validator;
  7. /**
  8.  * Created by wb-zhangkenan on 2016/9/2.
  9.  */
  10. public class PersonalValidtor implements Validator{
  11.     /**
  12.      * 判断支持的JavaBean类型
  13.      * @param aClass
  14.      * @return
  15.      */
  16.     @Override
  17.     public boolean supports(Class<?> aClass) {
  18.         return PersonScope.class.equals(aClass);
  19.     }
  20.     /**
  21.      * 实现Validator中的validate接口
  22.      * @param obj
  23.      * @param errors
  24.      */
  25.     @Override
  26.     public void validate(Object obj, Errors errors) {
  27.         //把校验信息注册到Error的实现类里
  28.         ValidationUtils.rejectIfEmpty(errors,"name",null,"姓名不能为空!");
  29.         PersonScope personScope = (PersonScope) obj;
  30.         if(StringUtils.isEmpty(personScope.getAddress())){
  31.             errors.rejectValue("address",null,"家庭地址不能为空!!!!");
  32.         }
  33.     }
  34. }

使用Validtor的校验实现类

我们需要在Controller的类里使用刚才写的Validtor的校验实现类来进行表单数据的校验。我们需要在Controller里用@InitBinder注解把刚才的校验类绑定到WebDataBinder类里。写法如下:

[java] view plain copy

 
  1. //绑定PersonalValidator
  2. @InitBinder
  3. public void initBinder(WebDataBinder webDataBinder){
  4.     webDataBinder.addValidators(new PersonalValidtor());
  5. }

接下来我们需要在@RequestMapping这个注解所在的方法上使用@Valid注解进行数据的校验。

[java] view plain copy

 
  1. @RequestMapping(value = "testPersonalValidtor.do")
  2. @ResponseBody
  3. //直接返回对象
  4. public Object testPersonalValidtor(@Valid PersonScope personScope, BindingResult bindingResult){
  5.     if(bindingResult.hasErrors()){
  6.         StringBuffer sb = new StringBuffer();
  7.         for(ObjectError objectError : bindingResult.getAllErrors()){
  8.             sb.append(((FieldError)objectError).getField() +" : ").append(objectError.getDefaultMessage());
  9.         }
  10.         return sb.toString();
  11.     }else{
  12.         return personScope;
  13.     }
  14. }
接下来我们来看一下效果:
请求:http://localhost:8081/testPersonalValidtor.do
结果:SpringMVC使用@Valid注解进行数据验证
请求:http://localhost:8081/testPersonalValidtor.do?name=张三&address=三元桥
结果:SpringMVC使用@Valid注解进行数据验证
具体Controller类代码如下:

[java] view plain copy

 
  1. package com.zkn.learnspringmvc.news.controller;
  2. import com.alibaba.fastjson.JSON;
  3. import com.zkn.learnspringmvc.scope.PersonScope;
  4. import com.zkn.learnspringmvc.validtor.PersonalValidtor;
  5. import org.springframework.stereotype.Controller;
  6. import org.springframework.validation.BindingResult;
  7. import org.springframework.validation.FieldError;
  8. import org.springframework.validation.ObjectError;
  9. import org.springframework.web.bind.WebDataBinder;
  10. import org.springframework.web.bind.annotation.InitBinder;
  11. import org.springframework.web.bind.annotation.RequestMapping;
  12. import org.springframework.web.bind.annotation.RequestMethod;
  13. import org.springframework.web.bind.annotation.ResponseBody;
  14. import javax.servlet.http.HttpServletResponse;
  15. import javax.validation.Valid;
  16. /**
  17.  * 用来测试PersonalValidator的控制器
  18.  * Created by wb-zhangkenan on 2016/9/2.
  19.  */
  20. @Controller
  21. public class TestPersonlalValidtorController {
  22.     //绑定PersonalValidator
  23.     @InitBinder
  24.     public void initBinder(WebDataBinder webDataBinder){
  25.         webDataBinder.addValidators(new PersonalValidtor());
  26.     }
  27.     @RequestMapping(value = "testPersonalValidtor.do")
  28.     @ResponseBody
  29.     //直接返回对象
  30.     public Object testPersonalValidtor(@Valid PersonScope personScope, BindingResult bindingResult){
  31.         if(bindingResult.hasErrors()){
  32.             StringBuffer sb = new StringBuffer();
  33.             for(ObjectError objectError : bindingResult.getAllErrors()){
  34.                 sb.append(((FieldError)objectError).getField() +" : ").append(objectError.getDefaultMessage());
  35.             }
  36.             return sb.toString();
  37.         }else{
  38.             return personScope;
  39.         }
  40.     }
  41. }

PersonScope实体类:

[java] view plain copy

 
  1. package com.zkn.learnspringmvc.scope;
  2. import java.io.Serializable;
  3. /**
  4.  * Person对象
  5.  * @author zkn
  6.  *
  7.  */
  8. public class PersonScope implements Serializable{
  9.     /**
  10.      * 序列
  11.      */
  12.     private static final long serialVersionUID = 1L;
  13.     /**
  14.      * 姓名
  15.      */
  16.     private String name;
  17.     /**
  18.      * 年龄
  19.      */
  20.     private Integer age;
  21.     /**
  22.      * 家庭地址
  23.      */
  24.     private String address;
  25.     private StudentScope studentScope;
  26.     public String getName() {
  27.         return name;
  28.     }
  29.     public void setName(String name) {
  30.         this.name = name;
  31.     }
  32.     public Integer getAge() {
  33.         return age;
  34.     }
  35.     public void setAge(Integer age) {
  36.         this.age = age;
  37.     }
  38.     @Override
  39.     public String toString() {
  40.         return "PersonDomain [name=" + name + ", age=" + age + "]";
  41.     }
  42.     public StudentScope getStudentScope() {
  43.         return studentScope;
  44.     }
  45.     public void setStudentScope(StudentScope studentScope) {
  46.         this.studentScope = studentScope;
  47.     }
  48.     public String getAddress() {
  49.         return address;
  50.     }
  51.     public void setAddress(String address) {
  52.         this.address = address;
  53.     }
  54. }
这里需要注意的是:@Valid要紧挨着JavaBean(即PersonScope),要不然不会生效的。
另外需要注意的是:这里的校验是哪个请求需要校验,就写在哪个请求上。如果需要配置全局的校验的话,可以在<mvc:annotation-driven/>中配置validator。写法如下:

[html] view plain copy

 
  1. <mvc:annotation-driven validator="personalValidtor">

[html] view plain copy

 
  1. <bean id="personalValidtor" class="com.zkn.learnspringmvc.validtor.PersonalValidtor"/>

使用<form:errors />标签

上面的错误信息的展示是我们自己来展示的错误信息,但是SpringMVC还给我们提供了一个<form:errors />标签来展示错误信息。例子如下:

[java] view plain copy

 
  1. @RequestMapping(value = "testPersonalValidtor02.do")
  2. public Object testPersonalValidtor01(@Valid PersonScope personScope, BindingResult bindingResult){
  3.     if(bindingResult.hasErrors()){
  4.         return "error";
  5.     }else{
  6.         return "home";
  7.     }
  8. }

jsp页面内容如下:

[html] view plain copy

  1. <%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
  2. <%@page pageEncoding="utf-8" contentType="text/html;utf-8"%>
  3. <form:errors path="personScope.name"/>
注意:<form:errors />标签是SpringMVC提供的,所以我们得引入这个标签库。<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
效果如下:SpringMVC使用@Valid注解进行数据验证