2012-04-13 4 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

답변

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 {}; 
} 

그런 다음 Validator 클래스는 다음과 같습니다 :

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

관련 문제