我有一个自定义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
内知道。
答案 0 :(得分:2)
你是对的!并且对于你想要的东西!,你可以在isValid()方法中构建约束违规消息。为此,约束Annotation应该特定于应用它的特定类,它应该是类级验证约束。在验证失败之前返回false之前的isValid里面你可以创建包含类实例值的消息。例如:
@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.
}
但我认为你想用Field级别的注释做到这一点!我不相信期待你的结果。
答案 1 :(得分: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
是我们实体上使用的自定义界面。我们还有一些其他接口和自定义处理,如上所示。