我们在做Form表单提交的时候,只在前端做数据校验是不够安全的,所以有时候我们需要在后端同样做数据的校验。好在SpringMVC在后台验证给我们提供了一个比较好的支持。那就是使用Valid接口的实现类做数据校验。在这之前我们先做一下准备的工作。
添加相关的Maven依赖
我们先把需要的jar包添加进来。
<dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.1.0.Final</version> </dependency> <dependency> <groupId>org.apache.bval</groupId> <artifactId>bval-jsr303</artifactId> <version>0.5</version> </dependency>
实现Validator接口
接下来的第一 步我们需要写一个类来实现Validator接口。在这个类里我们需要定义它支持校验的JavaBean,实现validate方法,用来进行相关的校验。具体的实现类如下:
package com.zkn.learnspringmvc.validtor; import com.zkn.learnspringmvc.scope.PersonScope; import org.springframework.util.StringUtils; import org.springframework.validation.Errors; import org.springframework.validation.ValidationUtils; import org.springframework.validation.Validator; /** * Created by wb-zhangkenan on 2016/9/2. */ public class PersonalValidtor implements Validator{ /** * 判断支持的JavaBean类型 * @param aClass * @return */ @Override public boolean supports(Class<?> aClass) { return PersonScope.class.equals(aClass); } /** * 实现Validator中的validate接口 * @param obj * @param errors */ @Override public void validate(Object obj, Errors errors) { //把校验信息注册到Error的实现类里 ValidationUtils.rejectIfEmpty(errors,"name",null,"姓名不能为空!"); PersonScope personScope = (PersonScope) obj; if(StringUtils.isEmpty(personScope.getAddress())){ errors.rejectValue("address",null,"家庭地址不能为空!!!!"); } } }
使用Validtor的校验实现类
我们需要在Controller的类里使用刚才写的Validtor的校验实现类来进行表单数据的校验。我们需要在Controller里用@InitBinder注解把刚才的校验类绑定到WebDataBinder类里。写法如下:
//绑定PersonalValidator @InitBinder public void initBinder(WebDataBinder webDataBinder){ webDataBinder.addValidators(new PersonalValidtor()); }接下来我们需要在@RequestMapping这个注解所在的方法上使用@Valid注解进行数据的校验。
@RequestMapping(value = "testPersonalValidtor.do") @ResponseBody //直接返回对象 public Object testPersonalValidtor(@Valid PersonScope personScope, BindingResult bindingResult){ if(bindingResult.hasErrors()){ StringBuffer sb = new StringBuffer(); for(ObjectError objectError : bindingResult.getAllErrors()){ sb.append(((FieldError)objectError).getField() +" : ").append(objectError.getDefaultMessage()); } return sb.toString(); }else{ return personScope; } }接下来我们来看一下效果:
请求:http://localhost:8081/testPersonalValidtor.do
结果:
请求:http://localhost:8081/testPersonalValidtor.do?name=张三&address=三元桥
结果:
具体Controller类代码如下:
package com.zkn.learnspringmvc.news.controller; import com.alibaba.fastjson.JSON; import com.zkn.learnspringmvc.scope.PersonScope; import com.zkn.learnspringmvc.validtor.PersonalValidtor; import org.springframework.stereotype.Controller; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.validation.ObjectError; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; /** * 用来测试PersonalValidator的控制器 * Created by wb-zhangkenan on 2016/9/2. */ @Controller public class TestPersonlalValidtorController { //绑定PersonalValidator @InitBinder public void initBinder(WebDataBinder webDataBinder){ webDataBinder.addValidators(new PersonalValidtor()); } @RequestMapping(value = "testPersonalValidtor.do") @ResponseBody //直接返回对象 public Object testPersonalValidtor(@Valid PersonScope personScope, BindingResult bindingResult){ if(bindingResult.hasErrors()){ StringBuffer sb = new StringBuffer(); for(ObjectError objectError : bindingResult.getAllErrors()){ sb.append(((FieldError)objectError).getField() +" : ").append(objectError.getDefaultMessage()); } return sb.toString(); }else{ return personScope; } } }PersonScope实体类:
package com.zkn.learnspringmvc.scope; import java.io.Serializable; /** * Person对象 * @author zkn * */ public class PersonScope implements Serializable{ /** * 序列 */ private static final long serialVersionUID = 1L; /** * 姓名 */ private String name; /** * 年龄 */ private Integer age; /** * 家庭地址 */ private String address; private StudentScope studentScope; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "PersonDomain [name=" + name + ", age=" + age + "]"; } public StudentScope getStudentScope() { return studentScope; } public void setStudentScope(StudentScope studentScope) { this.studentScope = studentScope; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }这里需要注意的是:@Valid要紧挨着JavaBean(即PersonScope),要不然不会生效的。
另外需要注意的是:这里的校验是哪个请求需要校验,就写在哪个请求上。如果需要配置全局的校验的话,可以在
<mvc:annotation-driven/>中配置validator。写法如下:
<mvc:annotation-driven validator="personalValidtor">
<bean id="personalValidtor" class="com.zkn.learnspringmvc.validtor.PersonalValidtor"/>
使用<form:errors />标签
上面的错误信息的展示是我们自己来展示的错误信息,但是SpringMVC还给我们提供了一个<form:errors />标签来展示错误信息。例子如下:
@RequestMapping(value = "testPersonalValidtor02.do") public Object testPersonalValidtor01(@Valid PersonScope personScope, BindingResult bindingResult){ if(bindingResult.hasErrors()){ return "error"; }else{ return "home"; } }jsp页面内容如下:
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <%@page pageEncoding="utf-8" contentType="text/html;utf-8"%> <form:errors path="personScope.name"/>注意:<form:errors />标签是SpringMVC提供的,所以我们得引入这个标签库。<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
效果如下: