2012-07-27 66 views
4

我使用Map作爲本地化值,區域設置作爲鍵和字符串作爲值。對於必填字段,我需要檢查是否至少設置了所需的語言環境 - 或者至少設置了一些值。我已經實現了驗證註釋以用於這樣的Map字段和相應的驗證器。問題是,我如何報告缺失值?這是在UI用來綁定字段錯誤/值屬性路徑,順心每次: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; 
    } 
} 

此錯誤的正確的路徑是「字段[音響]」,但看來我只能訪問索引子屬性。在這種情況下,對象本身被編入索引。我正在使用Hibernate驗證器。

回答

0

這是一個非常有趣的問題。現在我沒有時間來測試它自己:(,不過這傢伙在這裏:

Validation of a Collection

似乎能夠驗證元素的集合 因此,如果您切換到一個集合,而不是。一個Map(這應該是相當容易的),例如:

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

@LocalizationRequired 
List<LocaleToString> locales; 

您應該能夠達到你想要什麼,我覺得

+0

差異是實際驗證錯誤所綁定到的路徑。 Collection_的驗證報告集合級別(語言環境)而不是元素級別(語言環境[1])的所有錯誤。我試圖得到更具體的錯誤(對於Spring綁定)。我收到了一個非常強烈的感覺,這種用例在規範中被忽略了......也就是說,必須使用bean而不是索引文件。 – 2012-08-09 13:11:52

3

我沒能找到一種方法來報告的索引錯誤元素級別上的字段 - 這在規範中是否被忽略了?

這裏就是我所做的:

而是地圖的,我用了一個「嵌入」豆對所有支持的語言環境中的實際字段(如LocalizedString(字符串連接,字符串連接等),然後舉報的違規行爲這樣的:

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

這是在我們的情況下是可行的,因爲我們有一組預定義支持的語言,但它不能擴展到任意索引的索引字段。

進一步Spring的LocalValidatorFactoryBean或休眠瓦利dator沒有正確支持嵌入驗證。由於同一組件在不同驗證要求的不同地方使用,因此我不能在組件本身內使用@Valid以及實際驗證註釋 - 至少不支持@Valid上的驗證組。

與Spring的LocalValidatorFactoryBean或Hibernate驗證的問題是,ConstraintViolationinvalidValue被LocalizedString(「田」),而不是報道錯誤嵌套的字段(「field.fi」)的值。幸運的是這可以通過刪除「自定義FieldError登記從ConstraintViolation無效值」和報告錯誤覆蓋LocalValidatorFactoryBean.processConstraintViolations解決簡單地通過

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

這樣,春天可以解決invalidValue使用給出field