如何参数化Hibernate约束消息以包含字段名称



我有以下注释

@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 requiredMust be greater than 0这样的东西对我来说似乎非常合理,并且允许重用。

对于需要将这些冲突消息与属性关联的情况,只需迭代冲突,获取propertyPath并将路径和消息打印到日志或其他内容中。

在web框架中,我更喜欢这样做,迭代约束冲突,将它们添加到Map<String,String>中,其中键是propertyPath,值是冲突消息。然后在UI中,我将消息关联到字段的每个输入控件旁边,使内容保持简洁明了,同时便于用户理解和阅读。

相关内容

最新更新