9

我有一个自定义 bean 验证器,它检查实体上的给定字段在某些条件下是否是唯一的。如果验证失败,消息应该包含已经存在的实体的字段(例如 ID)。因此,例如消息应该是:

"Product 42 already has such a value defined, choose a unique value."

这可以使用 bean 验证吗?

AFAICS,消息格式可能包含参数,例如:

"Length must be between {min} and {max}."

但这只能引用验证注释的“静态”属性,在这种情况下:

@Size(min=1, max=16)
private String name;

就我而言,该值仅在isValid我的自定义验证器中已知。

4

2 回答 2

3

你是对的!,对于你想要的!,你可以在 isValid() 方法中构建约束冲突消息。为此,约束注释应该特定于已应用它的特定类,并且它应该是类级别的验证约束。在 isValid 内部,在验证失败返回 false 之前,您可以创建包含类实例值的消息。例如:

@check class Test{ int id; @validations...on fields}.

public boolean isValid(Test value, ConstraintValidatorContext context) 
{
// your check logic
context.disableDefaultConstraintViolation();
context.buildConstraintViolationWithTemplate("It should be different for(custom message) .."+ value.id).addConstraintViolation();
return false; // based on constraint filure.

}

但我认为你想用字段级注释来做到这一点!我不知道期待你的结果。

于 2011-01-22T15:35:13.693 回答
0

这并不是最好的解决方案,但我们最终做的是在我们的顶级异常处理代码中添加如下内容:

String getConstraintViolationMessages(ConstraintViolationException e) {
    StringBuilder sb = new StringBuilder();
    for (ConstraintViolation<?> violation : e.getConstraintViolations()) {
        sb.append(getMessage(violation));
        sb.append("\n");
    }
    sb.setLength(sb.length() - 1);
    return sb.toString();
}

String getMessage(ConstraintViolation<?> violation) {
    String key = violation.getMessageTemplate();
    String messageFormat = localize(key);

    Object entity = violation.getRootBean();
    String identifier;
    if (entity instanceof PrimaryKeyed) {
        identifier = String.valueOf(((PrimaryKeyed) entity).getId());
    } else {
        identifier = entity.toString();
    }

    return MessageFormat.format(messageFormat, identifier);
}

请注意,PrimaryKeyed这是在我们的实体上使用的自定义界面。我们还有一些其他接口和自定义处理,上面没有显示。

于 2013-09-09T11:33:26.953 回答