1. 程式人生 > >hiberbate validation 自定義註解

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

校驗信用卡號碼

沒有

@Email

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();
        }
    }
}