如何在Hibernate中覆盖验证注释中的属性?

时间:2014-11-25 13:25:43

标签: java spring hibernate validation

我有自定义注释,如下所示:

@Documented
@Constraint(validatedBy = MyValidator.class)
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {

    String message() default "message";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

验证器以验证内容:

public class MyValidator implements ConstraintValidator<MyAnnotation, String> {

    @Override
    public void initialize(MyAnnotation myAnnotation) {
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        ConstraintValidatorContextImpl con = (ConstraintValidatorContextImpl)context;

        String diff = getDiff(value, cleanForHTMLContext(value));
        if(diff.isEmpty()){
            return true;
        }
        return false;
    }

    private cleanForHTMLContext(String value) {
       // Some stuff to clean up value
    }

    private String getDiff(String value, String cleanedValue) {
       // Some stuff to compare values
    }
}

我的目标是添加&#34;差异&#34;注释属性,之后有可能通过ResourceBundle中的键和属性解析消息。

例如:当使用类型无效日期时,应该看到以下消息:

数据无效,因为包含此文本:{diff}。其中diff将是两个字符串之间的运行时比较结果,将在 isValid()方法中进行评估。< / p>

我试图像这样从地图参数中挖取值:

ConstraintValidatorContextImpl con = (ConstraintValidatorContextImpl)context;
con.getConstraintDescriptor().getAttributes().put("diff", value);

但不幸的是,我对ConstraintDescriptorImpl

中创建的不可修改的地图有例外

是否有其他可能性添加将使用错误代码解决的自定义属性?

1 个答案:

答案 0 :(得分:4)

我自己尝试过这个,如果你使用的是Hibernate Validator,下面的解决方案就可以了。请注意,您的消息必须包含${}以标记变量部分,而不是{}

private MyAnnotation annotation;

@Override
public void initialize(MyAnnotation a)
{
    this.annotation = a;
}

@Override
public boolean isValid(String value, ConstraintValidatorContext ctx)
{
    String diff = getDiff(value, cleanForHTMLContext(value));
    if (diff.isEmpty())
        return true;

    String message = annotation.message();
    HibernateConstraintValidatorContext hctx = ctx.unwrap(HibernateConstraintValidatorContext.class);

    ctx.disableDefaultConstraintViolation();
    ctx.addExpressionVariable("diff", diff)
       .buildConstraintViolationWithTemplate(message)
       .addConstraintViolation();
    return false;
}

请注意,您的邮件应包含${diff}作为模板,而不是{diff}

...
public @interface MyAnnotation {
    String message() default "Data invalid, because contain this text: ${diff}.";
...