构建Dynamic ConstraintViolation错误消息

Mis*_*sha 6 validation hibernate bean-validation

我编写了一个由自定义实现的验证注释ConstraintValidator.我还想生成非常具体的ConstraintViolation对象,这些对象使用在消息插值期间验证过程中计算的值.

public class CustomValidator 
  implements ConstraintValidator<CustomAnnotation, ValidatedType> {

...
  @Override
  public boolean isValid(ValidatedType value, ConstraintValidatorContext context) {
    // Figure out that the value is not valid.
    // Now, I want to add a violation whose error message requires arguments.
  }
}
Run Code Online (Sandbox Code Playgroud)

我的消息源中的假设错误消息:

CustomAnnotation.notValid = The supplied value {value} was not valid because {reason}.
Run Code Online (Sandbox Code Playgroud)

传递给isValid方法的上下文提供了用于构建约束违规的接口,并最终将其添加到上下文中.但是,我似乎无法弄清楚如何使用它.根据我正在使用的版本的这个文档,我可以添加bean和属性节点到违规.这些是我可以为违规定义指定的唯一附加细节,但我不明白它们如何映射到错误消息中的参数.

百万美元的问题:如何使用自定义验证器将动态参数传递给我的验证错误消息?我想使用用于构建违规的界面填写这些{value}{reason}字段ConstraintValidatorContext.

获取消息源的实例并在自定义验证器中插入消息不是一个选项 - 无论如何都会对来自验证的消息进行插值,并且内部插值将导致某些消息被插值两次,可能会消除转义单引号或我的消息定义文件中具有特殊含义的其他字符.

Gun*_*nar 12

使用标准化的Bean Valiation API是不可能的,但是在Biber参考实现的Hibernate Validator中有一种方法.

您需要将其解包ConstraintValidatorContext到a中HibernateConstraintValidatorContext,以便您访问该addExpressionVariable()方法:

public class MyFutureValidator implements ConstraintValidator<Future, Date> {

    public void initialize(Future constraintAnnotation) {}

    public boolean isValid(Date value, ConstraintValidatorContext context) {
        Date now = GregorianCalendar.getInstance().getTime();

        if ( value.before( now ) ) {
            HibernateConstraintValidatorContext hibernateContext =
                context.unwrap( HibernateConstraintValidatorContext.class );

            hibernateContext.disableDefaultConstraintViolation();
            hibernateContext.addExpressionVariable( "now", now )
                .buildConstraintViolationWithTemplate( "Must be after ${now}" )
                .addConstraintViolation();

            return false;
        }

        return true;
    }
}
Run Code Online (Sandbox Code Playgroud)

参考指南有更多细节.