數據校驗是任何一個應用程序都會用到的功能,不管是顯示層仍是持久層. 一般,相同的校驗邏輯會分散在各個層中, 這樣,不只浪費了時間還會致使錯誤的發生(譯註: 重複代碼). 爲了不重複, 開發人員常常會把這些校驗邏輯直接寫在領域模型裏面, 可是這樣又把領域模型代碼和校驗代碼混雜在了一塊兒, 而這些校驗邏輯更應該是描述領域模型的元數據.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