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

标签 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 {};
}

和 validator 以验证东西:

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
    }
}

我的目标是将“diff”添加到注释属性,然后可以通过 ResourceBundle 中的键和属性解析消息。

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

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

我试过像这样从映射参数中提取值:

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

但不幸的是,关于在 ConstraintDescriptorImpl

中创建的不可修改 map ,我遇到了异常

是否还有其他可能添加自定义属性,然后使用错误代码解析?

最佳答案

我自己试过了,如果您使用的是 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}.";
...

关于java - 如何覆盖 Hibernate 中验证注释中的属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27128004/

相关文章:

java - 静态资源+web-inf+Spring Boot

Java Spring MVC 使用正则表达式重定向

java - 错误页面重定向后,Spring Security身份验证为空

spring - 在多列上使用 Spring 数据中的不同值

java - Hibernate insert or update datetime mysql always get 12 :00:00 or 00:00:00

java - FxmlLoader.load() 不工作,我不知道为什么。我应该怎么办?

java - 如何在网页中显示数据库中的数据?

java - 如何使用特定的 JRE 交付我的 Java 应用程序?

java - Hibernate/JPA -> 可空值和对象?

java - ActiveMQ:消费者/生产者为同一队列实现不同的协议(protocol)?