序言
数据验证是任何一个应用程序都会用到的功能,显示层、业务层、数据访问层等等都会涉及。
通常,开发人员会把校验逻辑在各个层都去实现。这样做会产生重复的代码,不仅浪费时间,而且还会导致错误的发生。
比较合适的做法是,把要验证的模型抽象出来,放在领域模型中,然后单独对领域模型进行验证。
JSR 303 – Bean Validation 是一个数据验证的规范,2009 年 11 月确定最终方案。这种方案默认通过注解来描述,也可以使用XML来重载或扩展。它提供了内置的一些约束。
Hibernate Validator不仅实现了JSR 303 – Bean Validation规范,而且还扩展了一些新的约束。
一、Bean Validation内置约束介绍
约束 | 详细解释 |
---|---|
@Null |
被注释的元素必须为 null |
@NotNull |
被注释的元素必须不为 null |
@AssertTrue |
被注释的元素必须为 true |
@AssertFalse |
被注释的元素必须为 false |
@Min(value) |
被注释的元素必须是一个数字,其值必须大于等于指定的最小值 |
@Max(value) |
被注释的元素必须是一个数字,其值必须小于等于指定的最大值 |
@DecimalMin(value) |
被注释的元素必须是一个数字,其值必须大于等于指定的最小值 |
@DecimalMax(value) |
被注释的元素必须是一个数字,其值必须小于等于指定的最大值 |
@Size(max, min) |
被注释的元素的大小必须在指定的范围内 |
@Digits (integer, fraction) |
被注释的元素必须是一个数字,其值必须在可接受的范围内 |
@Past |
被注释的元素必须是一个过去的日期 |
@Future |
被注释的元素必须是一个将来的日期 |
@Pattern(value) |
被注释的元素必须符合指定的正则表达式 |
二、Hibernate Validator扩展验证介绍
约束 | 详细信息 |
---|---|
@Email |
被注释的元素必须是电子邮箱地址 |
@Length |
被注释的字符串的大小必须在指定的范围内 |
@NotEmpty |
被注释的字符串的必须非空 |
@Range |
被注释的元素必须在合适的范围内 |
三、Hibernate Validator开发步骤
手动方式导入需要导入如下jar包:
validation-api-1.0.0.GA.jar
hibernate-validator-4.3.1.Final.jar
slf4j-simple-1.5.6.jar
slf4j-api-1.5.6.jar
如果通过Maven管理依赖包的话,可以设置如下配置:
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>4.3.1.Final</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.5.6</version> </dependency>
Maven会自动将相关的依赖的包导入。
<!-- 默认的注解映射的支持 --> <mvc:annotation-driven validator="validator" conversion-service="conversion-service" /> <bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"> <property name="providerClass" value="org.hibernate.validator.HibernateValidator"/> <!--不设置则默认为classpath下的 ValidationMessages.properties --> <property name="validationMessageSource" ref="validatemessageSource"/> </bean> <bean id="conversion-service" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" /> <bean id="validatemessageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basename" value="classpath:validatemessages"/> <property name="fileEncodings" value="utf-8"/> <property name="cacheSeconds" value="120"/> </bean>
领域模型根据实际情况编写,一般是一个Model类,类中有一些属性。
这里以User类为例,User.java代码如下所示:
package com.uni2uni.model; import org.hibernate.validator.constraints.Email; import org.hibernate.validator.constraints.NotEmpty; import org.hibernate.validator.constraints.Range; public class User { @NotEmpty(message = "{username can not empty}") private String username; @NotEmpty(message = "{password can not empty}") private String password; @Range(min = 1, max = 200, message = "{age is 1-200}") private int age; @Email(message = "{email not correct}") private String email; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
package com.uni2uni.action; import javax.validation.Valid; import org.hibernate.validator.internal.util.privilegedactions.NewInstance; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.ModelAndView; import com.uni2uni.model.User; @Controller @RequestMapping(value="/validate") public class ValidateController { @RequestMapping(value="/test", method = {RequestMethod.GET}) public String test(Model model){ if(!model.containsAttribute("user")){ model.addAttribute("user",new User()); } return "validate-post"; } @RequestMapping(value="/testform", method = {RequestMethod.POST}) public String testform(Model model,@ModelAttribute("user") @Valid User user, BindingResult result){ if(result.hasErrors()){ return test(model); } return "validatesuccess"; } }
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>My JSP 'demo1-post.jsp' starting page</title> </head> <body> <form:form modelAttribute="user" method="post" action="/web/validate/testform"> <form:errors path="*"></form:errors> <br /> username:<input type="text" name="username"> <form:errors path="username"></form:errors> <br /> password:<input type="text" name="password"> <form:errors path="password"></form:errors> <br /> age:<input type="text" name="age"> <form:errors path="age"></form:errors> <br /> email:<input type="text" name="email"> <form:errors path="email"></form:errors> <br /> <input type="submit" value="提交" /> </form:form> </body> </html>
<form:errors path="*"></form:errors>代表显示所有错误。
四、验证Demo
下载:http://pan.baidu.com/s/1xpOZ0
五、知识扩展
验证的作用域不仅局限于字段、属性,在类级别上也可以通过约束进行验证,而且对类的约束可以支持继承。