我有以下注释
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = IdValidator.class)
public @interface Id {
String message() default "{Id field cannot be null}";
}
我在课堂上使用的
public class Person {
@Id
String firstName;
@Id
String lastName;
}
当我呼叫时
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
Set<ConstraintViolation<FakePerson>> violations = validator.validate(person);
我希望ConstrainstViolation
有一条消息,上面写着"firstName不能为null"。我该怎么做?
是否有方法创建与ConstraintValidator
内部路径关联的消息?
public class IdValidator implements ConstraintValidator<Id, Object> {
@Override
public boolean isValid(Object value, ConstraintValidatorContext context)
{
//Ideally I can build the messages associate with the property here with ConstraintValidatorContext
}
}
有几个选项。
第一种方法是在注释中添加一个新属性,如下所示为label
。
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PKFieldValidator.class)
public @interface Id {
String message() default "{Id field cannot be null}";
String label();
}
然后在课堂上,你会使用
@Id(label="firstName")
private String firstName;
@Id(label="lastName")
private String lastName;
然后简单地让你的信息像一样
Id.message={label} is required.
但这种方法的问题是,您将bean字段名称放入其他语言的翻译中。Se requiere el firstName
在西班牙语中有多大意义?
我的首选建议是实际保持bean验证消息的通用性。像Field is required
或Must be greater than 0
这样的东西对我来说似乎非常合理,并且允许重用。
对于需要将这些冲突消息与属性关联的情况,只需迭代冲突,获取propertyPath
并将路径和消息打印到日志或其他内容中。
在web框架中,我更喜欢这样做,迭代约束冲突,将它们添加到Map<String,String>
中,其中键是propertyPath
,值是冲突消息。然后在UI中,我将消息关联到字段的每个输入控件旁边,使内容保持简洁明了,同时便于用户理解和阅读。