2013-01-15 1 views
0

Date이 특정 연도에 발생하는지 확인하는 @Year이라는 사용자 지정 제약 조건을 작성했습니다. TimeUtil.NOW가 (상수 "now"를 포함) 현재 연도가 비교를 위해 촬영되는 것을 의미하기 때문에, 당신이 볼 수 있듯이빈 검증 : 복잡한 메시지 값 확인 - 방법은 무엇입니까?

year.message = must be a year between {min} and {max} 

, minmax이 문자열은 다음과 같습니다

@Documented 
@Retention(RetentionPolicy.RUNTIME) 
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD, ElementType.ANNOTATION_TYPE }) 
@Constraint(validatedBy = YearCheck.class) 
public @interface Year { 

    String message() default "{year.message}"; 

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

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

    /** 
    * The lower year. If not specified then no upper boundary check is performed.<br> 
    * Special values are: 
    * <ul> 
    * <li>{@link TimeUtil#NOW} for the current year 
    * </ul> 
    */ 
    String min() default ""; 

    /** 
    * The upper year. If not specified then no upper boundary check is performed.<br> 
    * Special values are: 
    * <ul> 
    * <li>{@link TimeUtil#NOW} for the current year 
    * </ul> 
    */ 
    String max() default ""; 
} 

ValidationMessages.properties에는 다음이 포함되어 있습니다. min 또는 max가 지정되지 않은 경우

또한, 그 의미, 해당 값은 무한

그래서, 문제는 min에 대한 예를 들어, 다음과 같습니다 어떻게 min이 설정되어 있는지 확인의 경우 수 번호가 아님 ("" 또는 "now") 메시지에 삽입 할 값을 어떻게 설정할 수 있습니까? @Year(min=1900,max=TimeUtil.NOW) 내가 유래에 대한 몇 가지 답변을 읽었습니다

must be a year between 1900 and 2013 

메시지를 생성해야합니다 예를 들어

는 문서를 읽을 수 있지만 나는) 가능 여부 확실하지 않다와 b) 나는이 작업을 수행해야 제약 조건 구현 또는 맞춤 MessageInterpolator

답변

1

어떻게 분 설정하고있는 경우는 숫자

당신은 주석이 ConstraintValidator 구현의 initialize() 방법의 속성에 액세스 할 수 없습니다 여부를 확인할 수 있습니다.

어떻게 메시지에 삽입 할 값을 설정할 수 있습니까?

은 직접이 작업을 수행 할 수는 없지만 전달 ConstraintValidatorContext 사용하여 검증의 isValid() 방법으로 메시지를 직접 만들 수 있습니다.

전부 당신의 검증은 다음과 같습니다

public class YearValidator implements ConstraintValidator<Year, String> { 

    private Date min; 
    private Date max; 

    @Override 
    public void initialize(Year constraintAnnotation) { 
     if(constraintAnnotation.min().equals("")) { 
      min = getMinimumDate(); 
     } 
     else if(constraintAnnotation.min().equals(TimeUtil.NOW)) { 
      min = getCurrentYear(); 
     } 
     else { 
      min = getYearFromString(constraintAnnotation.min()); 
     } 

     //same for max() 
} 

    @Override 
    public boolean isValid(Date value, ConstraintValidatorContext context) { 
     if(value == null) { 
      return true; 
     } 

     if(value.before(min) || value.after(max)) { 

      context.disableDefaultConstraintViolation(); 

      //load/create the error message and set min and max in it 
      String template = getTemplate(min, max); 

      context 
       .buildConstraintViolationWithTemplate(template) 
       .addConstraintViolation(); 

      return false; 
     } 

     return true; 
    } 
} 
+0

안녕 군나르을! 광범위한 답변 주셔서 감사합니다! 그러나 문제는'getTemplate (min, max)'부분입니다 :'context.getDefaultConstraintMessageTemplate()'는''{year.message} ''를 반환 할 것입니다. 그러나 어떻게하면 문자열에 접근 할 수 있습니까? 특히''ResourceBundleLocator '? 어쨌든, 당신의 대답을 정확하게 이해한다면,이 수준의 메시지 빌딩을 가로채는 방법은 없을까요? 예를 들어'{min}'과'{max}'의 값을 설정할 수 있습니다. – eerriicc

+0

나는 또한 내 자신의'MessageInterpolator'를 작성하려고 시도했지만,'context.getConstraintDescriptor(). getAttributes()'는'UnmodifiableMap'입니다. 'Context'를 복제하고 자신의 속성을 만들어야합니까? – eerriicc

+0

값을 직접 설정하는 것은 실제로 불가능합니다. String에 접근하기 위해, 당신은'ResourceBundle'을 직접로드 할 수 있습니다. – Gunnar