數據校驗是貫穿全部應用程序層(從表示層到持久層)的常見任務。一般在每一個層中實現相同的驗證邏輯,這是耗時且容易出錯的。這裏咱們可使用Hibernate Validator來幫助我處理這項任務。對此,Hibernate Validator提供了一些註解來做爲數據約束,咱們只須要將這些註解添加到咱們須要校驗的屬性/參數上面,就能夠輕鬆的完成這項任務。html
常見的註解,這裏只是列出了一些常見的屬性上面的約束以及他們所擁有的一些屬性,更加詳細的介紹請看 官方文檔。java
註解 | 數據類型 | 屬性 | 註解說明 | |
@NotNull | 字符串 | 添加註解的屬性不能是null | ||
@NotBlank | 字符串 | 檢查字符串是不是null,且去掉空格後長度是不是0 | ||
@AssertTrue | 布爾 | 檢查值是不是true | ||
@AssertFalse | 布爾 | 檢查值是不是false | ||
@DecimalMax | 數字 | 檢查值是否大於設定值 | ||
value | 設置的最大值 | |||
inclusive | 是否等於 | |||
@DecimalMin | 數字 | 檢查值是否小於設定值 | ||
value | 設置的最大值 | |||
inclusive | 是否等於 | |||
@Digits | 數字 | 校驗數字小數點先後位數 | ||
integer |
小數點前幾位 | |||
fraction |
小數點後幾位 | |||
字符串 | 校驗是否是郵箱 | |||
@Future | 時間 | 檢查日期是否是在未來 | ||
@Past | 時間 | 檢查日期是否在過去 | ||
@Max | 數字類型 | 是否大於最大值 | ||
@Min | 數字類型 | 是否小於最小值 | ||
@Pattern | 字符串 | 使用正則校驗 | ||
@Size | 字符串,集合,數組 | 檢查長度 |
看到上面的那麼多註解是否是以爲很實用呢?有沒有想試一試看看好很差用呢?接下來咱們開始寫一些代碼來用一用,首先咱們須要添加它的依賴。git
<dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.15.Final</version> </dependency> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.el</artifactId> <version>3.0.1-b09</version> </dependency>
接下來定義一個Class,而後在他的屬性上添加Hibernate Validator提供的一些註解數組
import lombok.Getter; import lombok.Setter; import lombok.ToString; import javax.validation.constraints.*; import java.util.Date; /** * 產品表 * * @author hejiaxuan */ @Getter @Setter @ToString public class Demo { @NotNull @Digits(integer = 0, fraction = 3) private Double aDouble; @Past(message = "time必須在今天以後") private Date time; @Max(value = 5, message = "status不能大於5") @Min(value = 0, message = "status不能小於0") @NotNull(message = "status不能爲null") private Integer status; @Size(min = 2, max = 5, message = "name長度必須在2~5之間") @NotBlank(message = "name不能爲null") private String name; }
對象定義好了,下面看看怎麼用吧。測試
上面的代碼中,咱們定義的了一個對象,而且在它的每一個屬性上面添加了咱們須要的校驗規則(註解)。如今說一個不須要實例化對象就能夠測試這些規則的方法, 代碼以下:ui
//單獨校驗Class中的某個屬性和值 Set<ConstraintViolation<Demo>> result = validator.validateValue(Demo.class, "name", "hahahaha"); Iterator<ConstraintViolation<Demo>> iterator = result.iterator(); while (iterator.hasNext()) { ConstraintViolation<Demo> next = iterator.next(); //打印校驗結果 System.out.println(next.getMessage()); } //運行結果 name長度必須在2~5之間
這裏是校驗這個對象的全部屬性hibernate
//待校驗對象 Demo demo = new Demo(); demo.setName("00000000"); demo.setADouble(200.001); demo.setStatus(200); //獲得Validator實例 ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); Validator validator = factory.getValidator(); //開始校驗 Set<ConstraintViolation<Demo>> result = validator.validate(demo); Iterator<ConstraintViolation<Demo>> iterator = result.iterator(); while (iterator.hasNext()) { ConstraintViolation<Demo> next = iterator.next(); //打印校驗結果 System.out.println(next.getMessage()); } //運行結果 name不能爲null 不能爲null status不能爲null
由於對象沒有設置任何值,因此校驗結果都是 「某某某字段不能爲null」,如今咱們給demo對象設置幾個值試一下code
demo.setName("00000000"); demo.setADouble(200.001); demo.setStatus(200); //運行結果 數字的值超出了容許範圍(只容許在0位整數和3位小數範圍內) status不能大於5 name長度必須在2~5之間
這裏是校驗整個對象的全部屬性,可是若是咱們只想校驗一個對象裏的部分屬性怎麼辦呢?xml
這裏是單獨校驗某一個對象其中的某幾個屬性,代碼以下htm
//第一個參數是要校驗的對象,後面的參數是要校驗的對象屬性名稱 Set<ConstraintViolation<Demo>> result = validator.validateProperty( demo, "status" ); //輸出結果 status不能大於5
上面講的都是對象屬性的校驗,那麼怎樣對一個方法的入參和出參進行校驗呢?這裏分爲 方法參數的校驗 和 返回值的校驗。下面咱們先給Demo.java添加一個方法,並添加約束註解:
public class Demo { /** * 要校驗的方法 * * @param string * @return */ public @Size(min = 3, max = 10, message = "結果長度在3~10之間") String getString(@NotBlank String string) { return string; } }
//對於方法的校驗 ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); ExecutableValidator executableValidator = factory.getValidator().forExecutables(); //實例化對象 Demo object = new Demo(); //獲取對應的方法 Method method = Demo.class.getMethod("getString", String.class); //獲取它的返回值 Object returnValue = method.invoke(object, "這是方法的參數,要大因而個字"); Set<ConstraintViolation<Demo>> violations = executableValidator.validateReturnValue( object, method, returnValue ); //結果 Iterator<ConstraintViolation<Demo>> iterator = violations.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().getMessage()); } //執行結果 結果長度在3~10之間
//對於方法的校驗 ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); ExecutableValidator executableValidator = factory.getValidator().forExecutables(); //實例化對象 Demo object = new Demo(); //獲取對應的方法 Method method = Demo.class.getMethod("getString", String.class); //方法的入參 Object[] parameters = {null}; Set<ConstraintViolation<Demo>> violations = executableValidator.validateParameters( object, method, parameters ); //結果 Iterator<ConstraintViolation<Demo>> iterator = violations.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next().getMessage()); } //執行結果 不能爲空