一:背景說明
驗證數據是一個常見的任務,它貫穿於所有應用層,從呈現到持久層。通常在每個層中都執行相同的驗證邏輯,耗時且容易出錯。為了避免這些驗證的重復,開發商往往把驗證邏輯直接進入的領域模型,在領域類的驗證碼,這真是對類本身的元數據。
只需要一個domain進行添加注解,然后在想要使用數據的層使用驗證即可。
二:Bean的注解說明
1.說明
在Bean驗證約束是通過java注釋表示。在本節中,您將學習如何使用這些注釋增強對象模型。有四種類型的bean約束:
-
field constraints:在使用字段級約束時,字段訪問策略用於訪問要驗證的值。這意味着驗證引擎直接訪問實例變量和不調用屬性訪問器方法,即使這樣一個訪問器的存在。
- 注意點雖然支持private或者public,是不支持static的字段
-
property constraints:如果你的模型類遵循JavaBeans規范,也可以放在領域類的屬性上標注,就是get方法上
- 注意點,不包括set方法
-
container element constraints:容器元素的約束
-
class constraints:類約束
附件一:bean約束
適用於field/property的約束
@AssertFalse
被注釋的元素必須為 false
@AssertTrue
被注釋的元素必須為 true
@DecimalMax(value=, inclusive=)
當包含inclusive
= false時,檢查帶注釋的值是否小於指定的最大值。否則值是否小於或等於指定的最大值。
參數值是根據BigDecimal的字符串表示的最大值的字符串表示形式。
@DecimalMin(value=, inclusive=)
當包含inclusive
= false時,檢查帶注釋的值是否大於指定的最小值。
否則值是否大於或等於指定的最小值。
參數值是根據BigDecimal字符串表示的值的字符串表示形式。
@Digits(integer=, fraction=)
檢查帶注釋的值是否是具有整數位數和小數位數的數字
@Email
被注釋的元素必須是電子郵箱地址
@Future
被注釋的元素必須是一個將來的日期
@FutureOrPresent
被注釋的元素必須是一個將來的日期或者現在
@Max(value=)
被注釋的元素必須是一個數字,其值必須小於等於指定的最大值
@Min(value=)
被注釋的元素必須是一個數字,其值必須大於等於指定的最小值
@NotBlank
被注釋的字符串的必須非空,同時,長度大於0
@NotEmpty
被注釋的字符串的必須非空,非null
@NotNull
被注釋的字符串的必須非空
@Negative
檢查元素是否嚴格負。零值被認為是無效的。
@NegativeOrZero
注釋的檢查元素是負或者零值。
@Null
注釋的元素必須是null
@Past
注釋的元素時間必須是過去的時間
@PastOrPresent
注釋的元素時間必須是過去或者當前
@Pattern(regex=, flags=)
被注釋的元素必須符合指定的正則表達式
@Positive
被注釋的元素必須是嚴格的正值,不包括零值
@PositiveOrZero
被注釋的元素是正值或者零
@Size(min=, max=)
被注釋的元素的大小必須在指定的范圍內,包含最大值
附件二:附加的約束
除了由Bean驗證API定義的約束,Hibernate Validator提供一些有用的自定義約束條件如下。適用於field/property的約束,只有“scriptassert是class級約束。
@CreditCardNumber(ignoreNonDigitCharacters=)
這個驗證旨在檢查用戶的錯誤,而不是信用卡的有效性
@Currency(value=)
驗證貨幣單位
@EAN
檢查注釋字符序列是一個有效的EAN條碼
@Length(min=, max=)
被注釋的字符串的大小必須在指定的范圍內
@Range(min=, max=)
被注釋的元素必須在合適的范圍內
@SafeHtml(whitelistType= , additionalTags=, additionalTagsWithAttributes=, baseURI=)
classpath中要有jsoup包
@URL(protocol=, host=, port=, regexp=, flags=)
被注釋的字符串必須是一個有效的url
@ScriptAssert(lang=, script=, alias=, reportOn=)
要有Java Scripting API
三:案例一(field的驗證)
1.pom
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>com.caojun.it</groupId> 8 <artifactId>hibernateValidator</artifactId> 9 <version>1.0-SNAPSHOT</version> 10 11 <!--hibernate validator--> 12 <dependencies> 13 <dependency> 14 <groupId>org.hibernate.validator</groupId> 15 <artifactId>hibernate-validator</artifactId> 16 <version>6.0.5.Final</version> 17 </dependency> 18 <dependency> 19 <groupId>org.glassfish</groupId> 20 <artifactId>javax.el</artifactId> 21 <version>3.0.1-b08</version> 22 </dependency> 23 <dependency> 24 <groupId>org.hibernate.validator</groupId> 25 <artifactId>hibernate-validator-cdi</artifactId> 26 <version>6.0.5.Final</version> 27 </dependency> 28 <dependency> 29 <groupId>junit</groupId> 30 <artifactId>junit</artifactId> 31 <version>4.11</version> 32 </dependency> 33 </dependencies> 34 35 </project>
2.Car.java
1 package org.hibernate.validator.referenceguide.chapter01; 2 3 import javax.validation.constraints.Min; 4 import javax.validation.constraints.NotNull; 5 import javax.validation.constraints.Size; 6 7 /** 8 * 對car的約束條件: 9 * manufacturer不為空 10 * licensePlate長度是2,14之間 11 * seatCount最小值是2 12 */ 13 public class Car { 14 @NotNull 15 private String manufacturer; 16 17 @NotNull 18 @Size(min = 2, max = 14) 19 private String licensePlate; 20 21 @Min(2) 22 private int seatCount; 23 24 public Car(){} 25 26 public Car(String manufacturer, String licencePlate, int seatCount) { 27 this.manufacturer = manufacturer; 28 this.licensePlate = licencePlate; 29 this.seatCount = seatCount; 30 } 31 32 public String getManufacturer() { 33 return manufacturer; 34 } 35 36 public void setManufacturer(String manufacturer) { 37 this.manufacturer = manufacturer; 38 } 39 40 public String getLicensePlate() { 41 return licensePlate; 42 } 43 44 public void setLicensePlate(String licensePlate) { 45 this.licensePlate = licensePlate; 46 } 47 48 public int getSeatCount() { 49 return seatCount; 50 } 51 52 public void setSeatCount(int seatCount) { 53 this.seatCount = seatCount; 54 } 55 }
3.測試案例
1 package org.hibernate.validator.referenceguide.chapter01; 2 3 import org.junit.BeforeClass; 4 import org.junit.Test; 5 6 import javax.validation.ConstraintViolation; 7 import javax.validation.Validation; 8 import javax.validation.Validator; 9 import javax.validation.ValidatorFactory; 10 import java.util.Iterator; 11 import java.util.Set; 12 13 import static org.junit.Assert.assertEquals; 14 15 /** 16 * 對car的測試類 17 */ 18 public class CarTest { 19 private static Validator validator; 20 21 /** 22 * 生成validator校驗器 23 */ 24 @BeforeClass 25 public static void setUpValidator() { 26 ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); 27 validator = factory.getValidator(); 28 } 29 30 /** 31 * 驗證整個Car 32 */ 33 @Test 34 public void test() { 35 Car car = new Car( null, "DD-AB-123", 1); 36 //如果有不符合的在validate后,會將錯誤信息存放到Set中 37 Set<ConstraintViolation<Car>> constraintViolations = validator.validate( car ); 38 //如果ite中沒有信息,就是正確的 39 Iterator<ConstraintViolation<Car>> ite = constraintViolations.iterator(); 40 while(ite.hasNext()) { 41 System.out.println(ite.next().getMessage()); 42 } 43 } 44 45 /** 46 * 單獨驗證Car對象中的某一個屬性,例如licensePlate 47 */ 48 @Test 49 public void licensePlateTooShort() { 50 Car car = new Car( "Morris", "D", 4 ); 51 52 Set<ConstraintViolation<Car>> constraintViolations = validator.validate( car ); 53 54 //這里使用junit中的斷言,斷言會出現一個exception 55 assertEquals( 1, constraintViolations.size() ); 56 57 } 58 59 60 }
四:案例二(property的驗證)
1.Car.java
1 package org.hibernate.validator.referenceguide.chapter02.propertylevel; 2 3 import javax.validation.constraints.AssertTrue; 4 import javax.validation.constraints.NotNull; 5 6 public class Car { 7 private String manufacturer; 8 9 private boolean isRegistered; 10 11 public Car(String manufacturer, boolean isRegistered) { 12 this.manufacturer = manufacturer; 13 this.isRegistered = isRegistered; 14 } 15 16 @NotNull 17 public String getManufacturer() { 18 return manufacturer; 19 } 20 21 public void setManufacturer(String manufacturer) { 22 this.manufacturer = manufacturer; 23 } 24 25 @AssertTrue 26 public boolean getIsRegistered() { 27 return isRegistered; 28 } 29 30 public void setRegistered(boolean isRegistered) { 31 this.isRegistered = isRegistered; 32 } 33 public Car(){} 34 35 }
2.CarTest.java
1 package org.hibernate.validator.referenceguide.chapter02.propertylevel; 2 import static org.junit.Assert.assertEquals; 3 4 import org.junit.BeforeClass; 5 import org.junit.Test; 6 7 import javax.validation.ConstraintViolation; 8 import javax.validation.Validation; 9 import javax.validation.Validator; 10 import javax.validation.ValidatorFactory; 11 import java.util.Iterator; 12 import java.util.Set; 13 14 public class CarTest { 15 private static Validator validator; 16 17 /** 18 * 生成validator校驗器 19 */ 20 @BeforeClass 21 public static void setUpValidator() { 22 ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); 23 validator = factory.getValidator(); 24 } 25 /** 26 * 驗證整個Car 27 */ 28 @Test 29 public void test() { 30 Car car=new Car("asaas",true); 31 //如果有不符合的在validate后,會將錯誤信息存放到Set中 32 Set<ConstraintViolation<Car>> constraintViolations = validator.validate( car ); 33 //如果ite中沒有信息,就是正確的 34 Iterator<ConstraintViolation<Car>> ite = constraintViolations.iterator(); 35 while(ite.hasNext()) { 36 System.out.println(ite.next().getMessage()); 37 } 38 } 39 }