如何参数化Hibernate Constraint消息以包含字段名称?

时间:2016-08-02 21:24:44

标签: java hibernate hibernate-validator

我有以下注释

@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不能为空”。我怎么能这样做?

有没有办法创建与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
  }
}

1 个答案:

答案 0 :(得分:1)

有几种选择。

第一种方法是在注释中添加新属性,如下所示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 requiredMust be greater than 0之类的内容对我来说似乎非常合理并允许重复使用。

对于需要将这些违规消息与属性相关联的情况,只需迭代违规,获取propertyPath并打印路径以及消息到您的日志或诸如此类的东西。

从Web框架来看,我更喜欢这样做,迭代约束违规,将它们添加到Map<String,String>,其中密钥是propertyPath,值是违规消息。然后在用户界面中,我将消息与每个字段的输入控件旁边相关联,保持内容干净简洁,方便用户理解和阅读。