校驗約束
一,認識Validator---Validation中最主要的接口
1.怎么獲取一個Validator--Validation.buildDefaultValidatorFactory()
對一個實體對象驗證之前首先需要有個 Validator 對象, 而這個對象是需要通過 Validation 類和
ValidatorFactory 來創建的. 最簡單的方法是調用 Validation.buildDefaultValidatorFactory() 這個
靜態方法
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
我們來看一下其api
1.<T> Set<ConstraintViolation<T>> validate(T object, Class<?>... groups) //使用 validate() 方法對一個給定的實體對象中定義的所有約束條件進行校驗 2.<T> Set<ConstraintViolation<T>> validateProperty(T object, String propertyName, Class<?>... groups) //通過 validateProperty() 可以對一個給定實體對象的單個屬性進行校驗. 其中屬性名稱需要符合 JavaBean規范中定義的屬性名稱. 3.<T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType, String propertyName, Object value, Class<?>... groups) //通過 validateValue() 方法,你能夠校驗如果把一個特定的值賦給一個類的某一個屬性的話,是否會 //違反此類中定義的約束條件.
我們可以發現:
所有的驗證方法都有一個用來指定的可變的參數。當我們執行證操作的時候,認證組是要指定的。如果沒有明確指定,則會用默認的認證組--javax.validation.groups.default
前面的Po如下:

package po; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; /** * Created by Administrator on 2016/7/12. */ 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; } }
對於上面的三種方法分別舉例如下:
@Test public void test1() { Car car = new Car(null, "DD-AB-123", 4); //validate() 方法會返回一個set的 ConstraintViolation 的實例的集合, 我們可以通過遍歷它來查看哪些驗證錯誤 Set<ConstraintViolation<Car>> constraintViolations = validator.validate(car); System.out.println(constraintViolations.size()); System.out.println(constraintViolations); }
@Test public void test2() { Car car = new Car(null, "DD-AB-123", 4); //validate() 方法會返回一個set的 ConstraintViolation 的實例的集合, 我們可以通過遍歷它來查看哪些驗證錯誤 Set<ConstraintViolation<Car>> constraintViolations = validator.validateProperty(car, "manufacturer"); System.out.println(constraintViolations.size()); System.out.println(constraintViolations); }
@Test public void test3() { //Car car = new Car(null, "DD-AB-123", 4); //validate() 方法會返回一個set的 ConstraintViolation 的實例的集合, 我們可以通過遍歷它來查看哪些驗證錯誤 Set<ConstraintViolation<Car>> constraintViolations = validator.validateValue(Car.class, "manufacturer", null); System.out.println(constraintViolations.size()); System.out.println(constraintViolations); }
注意:validateProperty() 和 validateValue() 會忽略被驗證屬性上定義的 @Valid .
二,現在來看看究竟 ConstraintViolation 是什么了. ConstraintViolation 中包含了很多方法能夠幫你快速定位究竟是什么導致了校驗失敗.下面列出 “ConstraintViolation 中的方法” 列出了這些方法:
--getMessage() 獲取(經過翻譯的)校驗錯誤信息
--getMessageTemplate() 獲取錯誤信息模版
--getRootBean() 獲取被校驗的根實體對象
--getRootBeanClass() 獲取被校驗的根實體類.
--getLeafBean() 如果約束是添加在一個bean(實體對象)上的,那么則返回這個bean的實例, 如果是約束是定義在一個屬性上的,則返回這個屬性所屬的bean的實例對象.
--getPropertyPath() 從被驗證的根對象到被驗證的屬性的路徑.
--getInvalidValue() 倒是校驗失敗的值. passengers
--getConstraintDescriptor() 導致校驗失敗的約束定義.
1.驗證失敗提示信息解析
每個約束定義中都包含有一個用於提示驗證結
果的消息模版, 並且在聲明一個約束條件的時候,你可以通過這個約束中的 message 屬性來重寫默認
的消息模版,如果在校驗的時候,這個約束條件沒有通過,那
么你配置的 MessageInterpolator 會被用來當成解析器來解析這個約束中定義的消息模版, 從而得到
最終的驗證失敗提示信息. 這個解析器會嘗試解析模版中的占位符( 大括號括起來的字符串 ).
其中, Hibernate Validator中默認的解析器 ( MessageInterpolator ) 會先在類路徑下找名稱為 ValidationMessages.properties 的 ResourceBundle , 然后將占位符和這個文件中定義的resource進
行匹配,如果匹配不成功的話,那么它會繼續匹配Hibernate Validator自帶的位於 /org/hibernate/
validator/ValidationMessages.properties 的 ResourceBundle , 依次類推,遞歸的匹配所有的占位符.
因為大括號{ 在這里是特殊字符,所以,你可以通過使用反斜線來對其進行轉義, 例如:
•\{ 被轉義成 {
•\} 被轉義成 }
•\\ 被轉義成 \
如果默認的消息解析器不能夠滿足你的需求,那么你也可以在創建 ValidatorFactory 的時候, 將其
替換為一個你自定義的 MessageInterpolator
下面是4.3.2下面ValidationMessages.properties
javax.validation.constraints.AssertFalse.message = must be false javax.validation.constraints.AssertTrue.message = must be true javax.validation.constraints.DecimalMax.message = must be less than or equal to {value} javax.validation.constraints.DecimalMin.message = must be greater than or equal to {value} javax.validation.constraints.Digits.message = numeric value out of bounds (<{integer} digits>.<{fraction} digits> expected) javax.validation.constraints.Future.message = must be in the future javax.validation.constraints.Max.message = must be less than or equal to {value} javax.validation.constraints.Min.message = must be greater than or equal to {value} javax.validation.constraints.NotNull.message = may not be null javax.validation.constraints.Null.message = must be null javax.validation.constraints.Past.message = must be in the past javax.validation.constraints.Pattern.message = must match "{regexp}" javax.validation.constraints.Size.message = size must be between {min} and {max} org.hibernate.validator.constraints.CreditCardNumber.message = invalid credit card number org.hibernate.validator.constraints.Email.message = not a well-formed email address org.hibernate.validator.constraints.Length.message = length must be between {min} and {max} org.hibernate.validator.constraints.NotBlank.message = may not be empty org.hibernate.validator.constraints.NotEmpty.message = may not be empty org.hibernate.validator.constraints.Range.message = must be between {min} and {max} org.hibernate.validator.constraints.SafeHtml.message = may have unsafe html content org.hibernate.validator.constraints.ScriptAssert.message = script expression "{script}" didn't evaluate to true org.hibernate.validator.constraints.URL.message = must be a valid URL org.hibernate.validator.constraints.br.CNPJ.message = invalid Brazilian corporate taxpayer registry number (CNPJ) org.hibernate.validator.constraints.br.CPF.message = invalid Brazilian individual taxpayer registry number (CPF) org.hibernate.validator.constraints.br.TituloEleitor.message = invalid Brazilian Voter ID card numb