2012-07-27 94 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