hiberbate validation 自定義註解
Hibernate Validator 是 Bean Validation 的參考實現 。Hibernate Validator 提供了 JSR 303 規範中所有內建 constraint 的實現,除此之外還有一些附加的 constraint。
1.maven中引入hibernate-validator對應的jar:
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>4.3.1.Final</version> </dependency>
2. Bean Validator內建的註解
Annotation |
支援的資料型別 |
作用 |
Hibernate metadata impact |
@AssertFalse |
Boolean, boolean |
判斷關聯屬性是否為布林值false |
沒有 |
@AssertTrue |
Boolean, boolean |
檢查帶註釋的元素是否正確。 | 沒有 |
@DecimalMax |
BigDecimal, BigInteger, String, byte, short, int,long |
被註解的值必須不大於約束中指定的最大值. 這個約束的引數是一個通過BigDecimal定義的最大值的字串表示. |
沒有 |
@DecimalMin |
BigDecimal, BigInteger, String, byte, short, int,long |
被註解的值必須不小於約束中指定的最小值. 這個約束的引數是一個通過BigDecimal定義的最小值的字串表示. |
沒有 |
@Digits(integer=, fraction=) |
BigDecimal, BigInteger, String, byte, short, int,long |
校驗整數位數和小數位數 |
對應的資料庫表字段會被設定精度(precision)和準度(scale). |
@Future |
java.util.Date, java.util.Calendar; |
檢查給定的日期是否比現在晚. |
沒有 |
@Max |
BigDecimal, BigInteger, byte, short, int, long |
檢查該值是否小於或等於約束條件中指定的最大值. |
會給對應的資料庫表字段新增一個check的約束條件. |
@Min |
BigDecimal, BigInteger, byte, short, int, |
檢查該值是否大於或等於約束條件中規定的最小值. |
會給對應的資料庫表字段新增一個check的約束條件. |
@NotNull |
Any type |
Checks that the annotated value is notnull. |
對應的表字段不允許為null. |
@Null |
Any type |
Checks that the annotated value is null. |
沒有 |
@Past |
java.util.Date, java.util.Calendar;
|
檢查註解物件中的值表示的日期比當前早. |
沒有 |
@Pattern(regex=, flag=) |
String |
檢查該字串是否能夠在match指定的情況下被regex定義的正則表示式匹配. |
沒有 |
@Size(min=, max=) |
String, Collection, Map and arrays |
校驗物件的size。本文作者認為前提是該物件有size()方法,String除外。 |
對應的資料庫表字段的長度會被設定成約束中定義的最大值. |
@Valid |
Any non-primitive type |
遞迴的對關聯物件進行校驗, 如果關聯物件是個集合或者陣列, 那麼對其中的元素進行遞迴校驗,如果是一個map,則對其中的值部分進行校驗. |
沒有 |
3. Hibernate Validator拓展的註解
Annotation |
支援的資料型別 |
作用 |
Hibernate metadata impact |
@CreditCardNumber |
String |
校驗信用卡號碼 |
沒有 |
|
String |
校驗郵件地址 |
沒有 |
@Length(min=, max=) |
String |
功能同@Size,但是隻支援String型別 |
對應的資料庫表字段的長度會被設定成約束中定義的最大值. |
@NotBlank |
String |
不為null,不為空值,不為全空格。功能強大於@NotEmpty |
沒有 |
@NotEmpty |
String,Collection,Map, arrays |
校驗是否為null或者為空值。功能強於@NotNull |
沒有 |
@Range(min=, max=) |
BigDecimal,BigInteger,String, byte,short, int,long |
判斷數值的範圍,不僅支援數值型別,還支援字串、位元組等等型別 |
沒有 |
@SafeHtml(whitelistType=, additionalTags=) |
CharSequence |
無使用價值 |
沒有 |
@ScriptAssert(lang=, script=, alias=) |
Any type |
無使用價值 |
沒有 |
@URL(protocol=, host=, port=, regexp=, flags=) |
String |
根據RFC2396檢查帶註釋的字串是否有效的URL。如果指定了任意可選的引數協議、主機或埠,則相應的URL片段必須與指定的值匹配。可選的引數regexp和標誌允許指定附加的正則表示式(包括udin)。正則表示式標誌,URL必須與之匹配。................................................. |
沒有 |
4. Validator框架拓展註解
Annotation |
支援的資料型別 |
作用 |
@NotEmptyPattern |
String |
在字串不為空的情況下,驗證是否匹配正則表示式 |
@ListStringPattern |
List<String> |
驗證集合中的字串是否滿足正則表示式 |
@DateValidator |
String |
驗證日期格式是否滿足正則表示式,Local為ENGLISH |
@DateFormatCheckPattern |
String |
驗證日期格式是否滿足正則表示式,Local為自己手動指定 |
5. 物件圖級聯校驗
Validator不僅能夠校驗單個例項物件,還可以校驗完整的物件圖。對於例項中的物件成員屬性,註解上@Valid,就可以被關聯校驗。
6. 約束條件組合校驗
在某些複雜的場景中, 可能還會有更多的約束條件被定義到同一個元素上面, 這可能會讓程式碼看起來有些複雜, 另外, 如果在另外的類裡面還有一個相同的屬性, 我們可能還要把這些約束條件再拷貝到這個屬性上, 但是這樣做又違反了 DRY 原則.這個問題可以通過使用組合約束條件來解決.
@NotNull @NotBlank @Target( { ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE }) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = {}) @Documented public @interface NotNullAndValidCheck { String message() default "必須不為null且屬性格式符合要求";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {}; } |
7.驗證失敗異常捕獲
驗證失敗將會丟擲BindException異常
BindingResult bindingResult = ((BindException) e).getBindingResult();
List<FieldError> fieldErrors = bindingResult.getFieldErrors();
Map<String, String> errorMsg = new HashMap<>();
for (FieldError fieldError : fieldErrors) {
errorMsg.put(fieldError.getField(), fieldError.getDefaultMessage());
}
8.自定義註解
驗證字串被格式化成集合,驗證集合的長度
@Target用於指定使用範圍,該處限定只能在欄位上使用
@Retention(RetentionPolicy.RUNTIME)表示註解在執行時可以通過反射獲取到
@Constraint(validatedBy = xxx.class)指定該註解校驗邏輯
8.1 驗證的註解
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
@Constraint(validatedBy = FormatStrValidator.class)
public @interface FormateStr {
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
String message() default "";
/**
* 分隔符
* @return
*/
String delimiter() default ",";
int min() default 0;
int max() default Integer.MAX_VALUE;
}
8.2 註解實現類
public class FormatStrValidator implements ConstraintValidator<FormateStr, String> {
private static final Log log = LoggerFactory.make();
private int min;
private int max;
private String delimiter;
@Override
public void initialize(FormateStr constraintAnnotation) {
min = constraintAnnotation.min();
max = constraintAnnotation.max();
delimiter = constraintAnnotation.delimiter();
validateParameters();
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
if(StringUtils.isBlank(value)) {
return true;
}
int length = value.split(delimiter).length;
return length >= min && length <= max;
}
private void validateParameters() {
if ( min < 0 ) {
throw log.getMinCannotBeNegativeException();
}
if ( max < 0 ) {
throw log.getMaxCannotBeNegativeException();
}
if ( max < min ) {
throw log.getLengthCannotBeNegativeException();
}
}
}