Java 您可以在运行时更改注释消息吗?

Java 您可以在运行时更改注释消息吗?,java,bean-validation,Java,Bean Validation,我试图在注释中包含一条动态消息,该消息根据传递给它的其他变量中的值更改文本的主体。我设置了一条默认消息,但当设置了某个指示器时,我想显示一条不同的消息。这可能吗 这是我的注解- @Target({TYPE, ANNOTATION_TYPE}) @Retention(RUNTIME) @Constraint(validatedBy = FieldMatchValidator.class) @Documented public @interface FieldMatch { Class<

我试图在注释中包含一条动态消息,该消息根据传递给它的其他变量中的值更改文本的主体。我设置了一条默认消息,但当设置了某个指示器时,我想显示一条不同的消息。这可能吗

这是我的注解-

@Target({TYPE, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = FieldMatchValidator.class)
@Documented
public @interface FieldMatch
{
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
    String first();
    String second();
    String third() default "";
    String match() default "true";
    String message() default "{error.theseValuesDontMatch}";

    /**
     * Defines several <code>@FieldMatch</code> annotations on the same element
     *
     * @see FieldMatch
     */
    @Target({TYPE, ANNOTATION_TYPE})
    @Retention(RUNTIME)
    @Documented @interface List
    {
        FieldMatch[] value();
    }
}
public class FieldMatchValidator implements ConstraintValidator<FieldMatch, Object>
{
    private String firstFieldName;
    private String secondFieldName;
    private String thirdFieldName;
    private String match;
    private String message;

    @Override
    public void initialize(FieldMatch constraintAnnotation)
    {
        firstFieldName = constraintAnnotation.first();
        secondFieldName = constraintAnnotation.second();
        thirdFieldName = constraintAnnotation.third();
        match = constraintAnnotation.match();
        if(match != null && !Boolean.getBoolean(match)){
            message = "error.theseValuesMustNotMatch";
        }
    }

    @Override
    public boolean isValid(final Object value, final ConstraintValidatorContext context)
    {
        try
        {
            final Object firstObj = BeanUtils.getProperty(value, firstFieldName);
            final Object secondObj = BeanUtils.getProperty(value, secondFieldName);
            final Object thirdObj = BeanUtils.getProperty(value, thirdFieldName);
            final String same = BeanUtils.getProperty(value, match);

            boolean valid = false;
            if(same != null && Boolean.getBoolean(same)){
                if("".equals(thirdObj)){
                    valid = firstObj == null && secondObj == null || firstObj != null && firstObj.equals(secondObj) ;
                }
                else{
                    valid = firstObj != null && firstObj.equals(secondObj) && firstObj.equals(thirdObj) ;   
                }
            }
            else{
                if("".equals(thirdObj)){
                    valid = firstObj == null && secondObj == null || firstObj != null && !firstObj.equals(secondObj) ;
                }
                else{
                    valid = firstObj != null && !(firstObj.equals(secondObj) && firstObj.equals(thirdObj)) ;   
                }
            }
            return valid ;
        }
        catch (final Exception ignore)
        {
            // ignore
        }
        return true;
    }
}
下面是注释使用的验证程序类-

@Target({TYPE, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = FieldMatchValidator.class)
@Documented
public @interface FieldMatch
{
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
    String first();
    String second();
    String third() default "";
    String match() default "true";
    String message() default "{error.theseValuesDontMatch}";

    /**
     * Defines several <code>@FieldMatch</code> annotations on the same element
     *
     * @see FieldMatch
     */
    @Target({TYPE, ANNOTATION_TYPE})
    @Retention(RUNTIME)
    @Documented @interface List
    {
        FieldMatch[] value();
    }
}
public class FieldMatchValidator implements ConstraintValidator<FieldMatch, Object>
{
    private String firstFieldName;
    private String secondFieldName;
    private String thirdFieldName;
    private String match;
    private String message;

    @Override
    public void initialize(FieldMatch constraintAnnotation)
    {
        firstFieldName = constraintAnnotation.first();
        secondFieldName = constraintAnnotation.second();
        thirdFieldName = constraintAnnotation.third();
        match = constraintAnnotation.match();
        if(match != null && !Boolean.getBoolean(match)){
            message = "error.theseValuesMustNotMatch";
        }
    }

    @Override
    public boolean isValid(final Object value, final ConstraintValidatorContext context)
    {
        try
        {
            final Object firstObj = BeanUtils.getProperty(value, firstFieldName);
            final Object secondObj = BeanUtils.getProperty(value, secondFieldName);
            final Object thirdObj = BeanUtils.getProperty(value, thirdFieldName);
            final String same = BeanUtils.getProperty(value, match);

            boolean valid = false;
            if(same != null && Boolean.getBoolean(same)){
                if("".equals(thirdObj)){
                    valid = firstObj == null && secondObj == null || firstObj != null && firstObj.equals(secondObj) ;
                }
                else{
                    valid = firstObj != null && firstObj.equals(secondObj) && firstObj.equals(thirdObj) ;   
                }
            }
            else{
                if("".equals(thirdObj)){
                    valid = firstObj == null && secondObj == null || firstObj != null && !firstObj.equals(secondObj) ;
                }
                else{
                    valid = firstObj != null && !(firstObj.equals(secondObj) && firstObj.equals(thirdObj)) ;   
                }
            }
            return valid ;
        }
        catch (final Exception ignore)
        {
            // ignore
        }
        return true;
    }
}

以下是我是如何做到这一点的-

@Override
public void initialize(FieldMatch constraintAnnotation)
{
    firstFieldName = constraintAnnotation.first();
    secondFieldName = constraintAnnotation.second();
    thirdFieldName = constraintAnnotation.third();
    match = constraintAnnotation.match();

    //set a message variable on initialization    
    if("true".equals(match)){
        message = constraintAnnotation.message();
    }
    else{
        message = "{password.error.threeQuestionsSameAnswer}";}
}

@Override
public boolean isValid(final Object value, final ConstraintValidatorContext context)
{
    Object firstObj = null;
    Object secondObj = null;
    Object thirdObj = null;

    //disable existing violation message
    context.disableDefaultConstraintViolation();
    //build new violation message and add it
    context.buildConstraintViolationWithTemplate(message).addConstraintViolation();

etc.........
}

你为什么要这么做?这将有助于理解您试图实现的目标……除了不同的信息之外,我希望避免为一个可以轻松完成的事情创建两个注释。要检查以确保字段匹配的批注和要检查以确保字段不匹配的批注之间的差异非常小。您可以仅在initialize方法中自定义“message”,还是在isValid中也可以这样做?@Vishal Biyani当然可以<代码>上下文.buildConstraintViolationWithTemplate(“任意”).addConstraintViolation()我刚刚测试过,它可以工作。