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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6048556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 14:07:24  来源:igfitidea点击:

Can you change an annotation message at run time?

javabean-validation

提问by coder

I'm trying to include a dynamic message in my annotation that changes the main body of the text based on the values that are found in the other variables that are passed to it. I set a default message, but when a certain indicator is set, I want to display a different message. Is this possible?

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

Here's my annotation -

这是我的注释-

@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();
    }
}

Here's the validator class used by the annotation -

这是注释使用的验证器类 -

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

The piece I'm most interested in is the code that reads -

我最感兴趣的部分是读取的代码 -

    if(match != null && !Boolean.getBoolean(match)){
        message = "password.error.theseValuesMustNotMatch";
    }

回答by coder

Here's how I was able to do this -

这是我如何做到这一点 -

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