序言
数据验证是任何一个应用程序都会用到的功能,显示层、业务层、数据访问层等等都会涉及。
通常,开发人员会把校验逻辑在各个层都去实现。这样做会产生重复的代码,不仅浪费时间,而且还会导致错误的发生。
比较合适的做法是,把要验证的模型抽象出来,放在领域模型中,然后单独对领域模型进行验证。
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开发步骤
(1)导入jar包
手动方式导入需要导入如下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会自动将相关的依赖的包导入。
(2)配置springMVC-servlet.xml
<!-- 默认的注解映射的支持 -->
<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>
(3)编写相应的领域模型
领域模型根据实际情况编写,一般是一个Model类,类中有一些属性。
(4)添加约束
这里以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;
}
}
(5)Controller层处理请求
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";
}
}
(6)在View层解析验证信息
<%@ 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>代表显示所有错误。
(7)测试验证效果
四、验证Demo
下载:http://pan.baidu.com/s/1xpOZ0
五、知识扩展
(1)关于验证的作用域
验证的作用域不仅局限于字段、属性,在类级别上也可以通过约束进行验证,而且对类的约束可以支持继承。