4

我将 Map 用于本地化值,将语言环境作为键,将字符串作为值。对于必填字段,我需要检查至少设置了必需的语言环境 - 或者至少设置了一些值。我已经实现了要在此类 Map 字段和相应的验证器上使用的验证注释。问题是,如何报告缺失值?UI 中用于绑定字段错误/值的属性路径每次都会出错:

// 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;
    }
}

此错误的正确路径是“field [fi]”,但看来我只能访问索引子属性。在这种情况下,对象本身被索引。我正在使用休眠验证器。

4

2 回答 2

3

我无法找到在元素级别报告索引字段错误的方法。- 这在规范中被忽略了吗?

这是我所做的:

我没有使用 Map,而是使用了一个“可嵌入”bean,其中包含所有支持的语言环境的实际字段(例如 LocalizedString(String fi,String en 等)。然后报告如下违规行为:

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

这在我们的案例中是可行的,因为我们有一组预定义的支持语言,但它不能扩展到具有任意索引的索引字段。

此外,SpringLocalValidatorFactoryBean或 Hibernate Validator 都不能正确支持可嵌入的验证。由于相同的组件在不同的地方使用不同的验证要求,我不能@Valid在组件本身内使用实际的验证注释——至少在不支持@Valid.

SpringLocalValidatorFactoryBean或 Hibernate Validator的问题在于其invalidValueConstraintViolationLocalizedString(“field”),而不是报告的错误嵌套字段(“field.fi”)的值。幸运的是,这可以 LocalValidatorFactoryBean.processConstraintViolations通过删除“从 ConstraintViolation 中删除具有无效值的自定义 FieldError 注册”并简单地报告错误来解决

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

这样 Spring 解决了invalidValueusing given field

于 2012-08-09T13:46:40.800 回答
0

这是一个非常有趣的问题。现在我没有时间自己测试它:(,但是这里的这个人:

集合的验证

似乎能够验证元素的集合。因此,如果您切换到 Collection 而不是 Map(这应该相当容易),例如:

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

 @LocalizationRequired
 List<LocaleToString> locales;

我认为你应该能够实现你想要的。

于 2012-08-06T05:59:29.657 回答