2012-07-27 2 views
4

로캘을 키로, 문자열을 값으로 사용하여 지역화 된 값에 Map을 사용합니다. 필수 필드의 경우 최소한 필수 로케일이 설정되어 있는지 확인하거나 적어도 일부 값이 설정되어 있는지 확인해야합니다. 필자는 Map 필드와 해당 유효성 검사기에서 사용할 유효성 검사 주석을 구현했습니다. 문제는 누락 된 값을 어떻게보고 할 수 있는가입니다.Javax 유효성 검사 : 맵에 대한 제약 조건 위반

// Domain object: 
@LocalizationRequired 
private Map<Locale, String> field; 


// LocalizationRequiredValidator: 
public boolean isValid(Map<Locale, String> map, ConstraintValidatorContext context) { 
    if (requiredLocales.isEmpty()) { 
     // Check that there exists any not null value 
    } else { 
     context.disableDefaultConstraintViolation(); 
     boolean valid = true; 
     for (Locale requiredLocale : requiredLocales) { 
      if (map.get(requiredLocale) == null) { // e.g. fi 
       valid = false; 
       context.buildConstraintViolationWithTemplate("LocalizationRequired") 
       // These end up in wrong property path: 
       // .addNode(requiredLocale) 
       // --> field.fi 
       // .addNode("[" + requiredLocale + "]") 
       // --> field.[fi] 
       // .addNode(null).addNode(requiredLocale).inIterable() 
       // --> field.fi 
       // .addNode(null).addNode(null).inIterable().atKey(requiredLocale) 
       // --> field 
       .addConstraintViolation(); 
      } 
     } 
     return valid; 
    } 
} 

이 오류의 정확한 경로 "필드 [Fi를]"이다하지만 I 단지 인덱스 서브 속성을 액세스 할 수있는 표시 : 필드 오류/값을 바인딩하는 UI에 사용되는 속성 경로마다 잘못 . 이 경우 개체 자체가 인덱싱됩니다. 나는 Hibernate Validator를 사용하고있다.

답변

0

이것은 매우 흥미로운 질문입니다. 지금은 :(자신을 테스트 할 시간이 없어,하지만 여기이 사람은 :

Validation of a Collection

요소의 컬렉션의 유효성을 검사 할 수있을 것 같습니다 을 그래서 당신은 대신 컬렉션으로 전환합니다. 예를 들어지도 (아주 쉽게해야한다) :.

class LocaleToString { 
     private Locale locale; 
     private String language; 
} 

@LocalizationRequired 
List<LocaleToString> locales; 

당신은 내가 생각하기에, 원하는 것을 달성 할 수 있어야한다

+0

차이점은 실제 유효성 검사 오류가 바인딩되는 경로입니다. _ Collection_Valueation은 요소 수준 (로캘 [1]) 대신 컬렉션 수준 (로캘)의 모든 오류를보고합니다. 더 구체적인 오류 (스프링 바인딩 용)를 얻으려고했습니다. 이런 종류의 사용 사례가 스펙에서 간과되었다는 느낌이 강해졌습니다. 즉, 인덱스 파일 대신 빈을 사용해야합니다. –

3

나는 색인에 대한 오류를보고 할 수있는 방법을 찾을 수 없습니다 요소 레벨의 필드. 이것이 사양에서 간과 되었습니까? 여기

내가 무슨 짓을했는지 대신지도의

을, 나는 모든 지원되는 로케일의 실제 필드 (그렇다면이 같은 위반을보고 예를 들어 LocalizedString (문자열 Fi를, 문자열 엉 등)와 함께 "임베드"콩을 사용했다. :

context.buildConstraintViolationWithTemplate("LocalizationRequired") 
.addNode(requiredLocale) 
.addConstraintViolation(); 

우리가 지원되는 언어의 사전 정의 된 세트를 가지고 이것은 우리의 경우에 가능하다, 그러나 임의의 인덱스와 인덱스 필드로 확장되지 않습니다.

더 나아가 하나 봄의 LocalValidatorFactoryBean 또는 최대 절전 모드 VALI dator이 삽입 가능 파일의 유효성 검사를 제대로 지원하지 않습니다. 동일한 구성 요소가 서로 다른 유효성 검사 요구 사항을 가진 다른 위치에서 사용되기 때문에 @Valid의 유효성 검사 그룹에 대한 지원이 적어도없는 경우 @Valid을 구성 요소 자체에 실제 유효성 검사 주석과 함께 사용할 수 없습니다.

봄의 LocalValidatorFactoryBean 또는 최대 절전 모드 검사기의 문제는 ConstraintViolationinvalidValue는 ("필드") 대신보고 잘못된 중첩 된 필드 ("field.fi")의 값을 LocalizedString 점이다. 다행히이 단순히

errors.rejectValue(field, errorCode, errorArgs, violation.getMessage()); 

에 의해 "ConstraintViolation에서 잘못된 값으로 정의 FieldError 등록"저를 제거하고 오류를보고하여 LocalValidatorFactoryBean.processConstraintViolations를 재정 의하여 해결 될 수있는이 방법 봄이 invalidValue 해결이 field을 주어 사용.