数据校验是任何一个应用程序都会用到的功能,不管是显示层仍是持久层. 一般,相同的校验逻辑会分散在各个层中, 这样,不只浪费了时间还会致使错误的发生(译注: 重复代码). 为了不重复, 开发人员常常会把这些校验逻辑直接写在领域模型里面, 可是这样又把领域模型代码和校验代码混杂在了一块儿, 而这些校验逻辑更应该是描述领域模型的元数据.node
JSR 303 - Bean Validation - 为实体验证定义了元数据模型和API. 默认的元数据模型是经过Annotations来描述的,可是也可使用XML来重载或者扩展. Bean Validation API 并不局限于应用程序的某一层或者哪一种编程模型, 例如,如图所示, Bean Validation 能够被用在任何一层, 或者是像相似Swing的富客户端程序中.git
Hibernate Validator is the reference implementation of this JSR. The implementation itself as well as the Bean Validation API and TCK are all provided and distributed under the Apache Software License 2.0.github
本章将会告诉你如何使用Hibernate Validator, 在开始以前,你须要准备好下面的环境:正则表达式
A JDK >= 5数据库
Apache Mavenexpress
网络链接 ( Maven须要经过互联网下载所需的类库)apache
A properly configured remote repository. Add the following to your settings.xml
:
例 1.1. Configuring the JBoss Maven repository
<repositories> <repository> <id>jboss-public-repository-group</id> <url>https://repository.jboss.org/nexus/content/groups/public-jboss</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> </repositories>
More information about settings.xml
can be found in the Maven Local Settings Model.
Hibernate Validator uses JAXB for XML parsing. JAXB is part of the Java Class Library since Java 6 which means that if you run Hibernate Validator with Java 5 you will have to add additional JAXB dependencies. Using Maven you have to add the following dependencies:
<dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.2</version> </dependency> <dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>2.1.12</version> </dependency>
if you are using the SourceForge package you find the necessary libraries in the lib/jdk5
directory. In case you are not using the XML configuration you can also disable it explicitly by calling Configuration.ignoreXmlConfiguration()
during ValidationFactory
creation. In this case the JAXB dependencies are not needed.
使用Maven archetype插件来建立一个新的Maven 项目
例 1.2. 使用Maven archetype 插件来建立一个简单的基于Hibernate Validator的项目
mvn archetype:generate -DarchetypeGroupId=org.hibernate \ -DarchetypeArtifactId=hibernate-validator-quickstart-archetype \ -DarchetypeVersion=4.2.0.Final \ -DarchetypeRepository=http://repository.jboss.org/nexus/content/groups/public-jboss/ \ -DgroupId=com.mycompany \ -DartifactId=hv-quickstart
Maven 将会把你的项目建立在hv-quickstart目录中. 进入这个目录而且执行:
mvn test
这样, Maven会编译示例代码而且运行单元测试, 接下来,让咱们看看生成的代码.
From version 4.2.0.Beta2, the maven command mvn archetype:create
will be no longer supported and will fail. You should use the command described in the above listing. If you want more details, look at Maven Archetype plugin page.
例 1.3. 带约束性标注(annotated with constraints)的Car 类
package com.mycompany; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; public class Car { @NotNull private String manufacturer; @NotNull @Size(min = 2, max = 14) private String licensePlate; @Min(2) private int seatCount; public Car(String manufacturer, String licencePlate, int seatCount) { this.manufacturer = manufacturer; this.licensePlate = licencePlate; this.seatCount = seatCount; } //getters and setters ... }
@NotNull
, @Size
and @Min
就是上面所属的约束性标注( constraint annotations), 咱们就是使用它们来声明约束, 例如在Car
的字段中咱们能够看到:
manufacturer永远不能为null
licensePlate永远不能为null,而且它的值字符串的长度要在2到14之间
seatCount的值要不能小于2
咱们须要使用Validator
来对上面的那些约束进行校验. 让咱们来看看CarTest
这个类:
例 1.4. 在CarTest中使用校验
package com.mycompany; import static org.junit.Assert.*; import java.util.Set; import javax.validation.ConstraintViolation; import javax.validation.Validation; import javax.validation.Validator; import javax.validation.ValidatorFactory; import org.junit.BeforeClass; import org.junit.Test; public class CarTest { private static Validator validator; @BeforeClass public static void setUp() { ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); validator = factory.getValidator(); } @Test public void manufacturerIsNull() { Car car = new Car(null, "DD-AB-123", 4); Set<ConstraintViolation<Car>> constraintViolations = validator.validate(car); assertEquals(1, constraintViolations.size()); assertEquals("may not be null", constraintViolations.iterator().next().getMessage()); } @Test public void licensePlateTooShort() { Car car = new Car("Morris", "D", 4); Set<ConstraintViolation<Car>> constraintViolations = validator.validate(car); assertEquals(1, constraintViolations.size()); assertEquals("size must be between 2 and 14", constraintViolations.iterator().next().getMessage()); } @Test public void