2012-04-13 93 views
1

編寫自定義約束時,可以通過一個驗證器實現驗證多個批註。例如,我有幾個註釋,它們規定了不同的@size註釋,但是我希望它們都指向相同的驗證器類,它執行一些全局檢查,即所有驗證器都必須匹配某個正則表達式。據我所見,該實現需要一個註釋類型。JSR-303 Bean驗證 - 自定義約束對一個驗證器的多個批註

一個註釋

@Target({ METHOD, FIELD, ANNOTATION_TYPE, TYPE}) 
@Retention(RetentionPolicy.RUNTIME) 
@Constraint(validatedBy = {UCNValidator.class}) 
@Documented 
@Size(min = 9, max = 9, message = "{exactlength}") 
public @interface UCN { 

    String message() default "{invalidFormat}"; 

    Class<?>[] groups() default {}; 

    Class<? extends Payload>[] payload() default {}; 

    String fieldName() default "ucn"; 

} 

驗證器

public class UCNValidator implements ConstraintValidator<UCN, String> 
{ 

    private String pattern = "[a-zA-Z].*"; 
    private String fieldName; 

    @Override 
    public void initialize(UCN constraintAnnotation) 
    { 
     this.fieldName = constraintAnnotation.fieldName(); 
    } 

    @Override 
    public boolean isValid(String value, ConstraintValidatorContext constraintValidatorContext) 
    { 

     if (value != null) 
     { 
      if (!value.matches(pattern)) 
      { 
       //do some stuff 
       return false; 
      } 

     } 

     return true; 

    } 
+0

決定這不是在任何情況下最好的前進方向。對於常見的驗證功能,我可以只寫一個所有驗證器使用的常用方法。 – andyfinch 2012-04-27 13:17:59

回答

0

似乎有不被驗證其屬性之一,當從對象訪問其他值的方法。我使用的解決方案是將註釋放在類上,然後驗證器將獲取整個對象以進行驗證,並且您只能訪問執行驗證所需的信息。

這裏有一個我寫的相互比較的對象的兩個不同的特性:

@Target(TYPE) 
@Retention(RUNTIME) 
@Constraint(validatedBy = LessThanValidator.class) 
@Documented 
public @interface LessThan { 

    String message() default "{com.bullethq.constraints.LessThan}"; 

    String bigValueProperty(); 

    String littleValueProperty(); 

    Class<?>[] groups() default {}; 

    Class<? extends Payload>[] payload() default {}; 
} 

然後驗證類:

public class LessThanValidator implements ConstraintValidator<LessThan, Object> { 

    private LessThan constraint; 

    public void initialize(LessThan constraintAnnotation) { 
     constraint = constraintAnnotation; 
    } 

    public boolean isValid(Object object, ConstraintValidatorContext cvc) { 
     Object bigValue = getValue(object, constraint.bigValueProperty()); 
     Object littleValue = getValue(object, constraint.littleValueProperty()); 

     // If one of the values is null, then we do not perform validation. 
     if (bigValue == null || littleValue == null) { 
      return true; 
     } 

     if (bigValue instanceof Comparable && littleValue instanceof Comparable) { 
      boolean valid = ((Comparable<Object>) bigValue).compareTo(littleValue) > 0; 
      if (!valid) { 
       // If the values are not valid, then build a custom violations which has the correct path in it. 
       cvc.buildConstraintViolationWithTemplate(cvc.getDefaultConstraintMessageTemplate()) 
         .addNode(constraint.littleValueProperty()) 
         .addConstraintViolation().disableDefaultConstraintViolation(); 
      } 
      return valid; 
     } 
     throw new IllegalArgumentException("Properties " + constraint.bigValueProperty() + " and " + constraint.littleValueProperty() + " both need to be comparable in " + object.getClass()); 
    } 
} 

的的getValue()方法只是一個靜態方法使用反射從對象中獲取值。

+0

如果你可以發佈'getValue'的代碼,它會有更多的幫助 – dakait 2013-02-04 05:45:24

相關問題