2014-09-03 2 views
1

필드에 String이라는 필드가 있고이 필드에 주어진 정규 표현식과 일치하는 필드의 내용을 적용하는 @Pattern 주석을 정의했습니다. 이제 정규 표현식과 일치하지 않는 첫 번째 문자가 정의 된 유효성 검사 오류 메시지에 표시된다는 제약 조건을 매개 변수화 할 수 있는지 여부가 궁금합니다. 제약 조건 위반이 직접 주석에 정의되지 않은 위해 javax.validation.constraints.Pattern annotation에 대한 매개 변수가있는 오류 메시지?

가 더 악화하려면 오류 메시지가 표시 될 수 있습니다,하지만 프로퍼티 파일 내에서, 예에서와 같이 다음과 같습니다 :

예 클래스 :

public class Address { 
    @Pattern(regexp="[a-zA-Z]*", message="paremeterizedMessage") 
    private String street; 
} 

예 특성 파일 :

parameterizedMessage = Invalid character {0}. Only characters a-z, A-Z allowed. 

이 javax.validation에 그런 일을 할 수 있습니까? @Pattern 주석은 오류 메시지를 매개 변수화 할 수 없다고 가정합니다. 그러나 매개 변수화 된 유효성 검사 메시지를 사용하여 ConstraintValidator을 정의 할 수 있습니까?

답변

0

일부 검증 주석과 같은 @Size(min=1,max=5)The String must have a length of {min} to {max} characters. 그들의 주석 매개 변수 매개 변수 오류 메시지를 수 있다는 사실을 고려할 때, 나는 장소 홀더와 일반적으로 파라미터 오류 메시지에 대한 해결책을 발견 등 {0}, {1}, ... :

는 등의 자체 검증 제약 조건을 정의 유효성 검사기 클래스 내에서

@Constraint(validatedBy=OnlyCharactersAllowedValidator.class) 
@Documented 
@Target({ElementType.FIELD}) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface OnlyCharactersAllowed { 
    String message() default "parameterizedMessage"; 
    Class<?>[] groups() default {}; 
    Class<? extends Payload>[] payload() default {}; 
} 

, 반사 모든 주석 매개 변수 (예 :를 저장하는 맵을 확장하는 데 사용할 수 있습니다및 max@Size 용) 및 추가 매개 변수 유효성 검사 메시지가 같은 속성 정보 파일에 정의되어있는 경우이 솔루션도 작동 키 0, 1 등 :

public class OnlyCharactersAllowedValidator implements ConstraintValidator<OnlyCharactersAllowed,String> 
{ 
    private static final String validCharacters = "abcdefghijklmnopqrstuvwxyz"; 
    @Override 
    public boolean isValid(String text, ConstraintValidatorContext constraintContext) 
    { 
     for (int index = 0; index < text.length; index++) { 
      String aCharacter = text.substring(index, index+1); 
      if (validCharacters.indexOf(aCharacter) < 0) { 
       /* Within this message call the magic happens: {0} is mapped to the invalid character. */ 
       addMessageParameter(constraintContext, aCharacter); 
       /* Create violation message manually and suppress the default message. */ constraintContext.buildConstraintViolationWithTemplate(constraintContext.getDefaultConstraintMessageTemplate()).addConstraintViolation(); 
       constraintContext.disableDefaultConstraintViolation(); 
       /* No further validation: show only one error message for invalid characters. */ 
       break; 
      } 
     } 
    } 

    private void addMessageParameter(ConstraintValidatorContext constraintContext, Object... parameter) 
    { 
     try 
     { 
      /* Get map for parameters (reflection necessary). */ 
      Field descriptorField = ConstraintValidatorContextImpl.class.getDeclaredField("constraintDescriptor"); 
      descriptorField.setAccessible(true); 
      @SuppressWarnings("unchecked") 
      ConstraintDescriptorImpl<OnlyCharactersAllowed> descriptor = (ConstraintDescriptorImpl<OnlyCharactersAllowed>) descriptorField.get(constraintContext); 

      Map<String,Object> attributes = descriptor.getAttributes(); 

      /* Copy immutable Map to new Map. */ 
      Map<String,Object> newAttributes = new HashMap<String,Object>(attributes.size() + parameter.length); 
      for (String key : attributes.keySet()) 
      { 
       newAttributes.put(key, attributes.get(key)); 
      } 

      /* Add given parameters to attributes. */ 
      Integer parameterCounter = 0; 
      for (Object param : parameter) 
      { 
       newAttributes.put(parameterCounter.toString(), param); 
       parameterCounter++; 
      } 

      /* Set new Map in Descriptor (reflection necessary). */ 
      Field attributesField = ConstraintDescriptorImpl.class.getDeclaredField("attributes"); 
      attributesField.setAccessible(true); 
      attributesField.set(descriptor, newAttributes); 
     } 
     catch (NoSuchFieldException | IllegalAccessException | SecurityException | ClassCastException e1) 
     { 
      /* Do nothing in case of exception. Unparameterized message is shown. */ 
     } 
    } 
} 

추가 할 수 있습니다.

parameterizedMessage = Invalid character: Do not use the {0} character. 
+0

안녕하세요 Claas, validCharacters가 사용되지 않고 text.length가 확인되지 않았습니다. 나는 왜 캐릭터를 하나 하나 파싱 하는지를 볼 수 없다. – Stephane

+0

안녕하세요. Stephane, 발언에 감사드립니다. 예제에서 일부 회사의 생산적 코드를 익명화하려고 시도하면서 오류가있었습니다. 이제는 더 합리적인 것이어야합니다. –

관련 문제