È possibile modificare un messaggio di annotazione in fase di esecuzione?

2022-07-29 13:00:29

Sto cercando di includere un messaggio dinamico nella mia annotazione che modifichi il corpo principale del testo in base ai valori che si trovano nelle altre variabili che gli vengono passate. Ho impostato un messaggio predefinito, ma quando è impostato un determinato indicatore, voglio visualizzare un messaggio diverso. È possibile?

Ecco la mia annotazione -

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

Ecco la classe di validazione utilizzata dall'annotazione -

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

Il pezzo che mi interessa di più è il codice che legge -

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

- coder

Source
Risposta


31
  • Ecco come sono riuscito a farlo -

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