2011-05-18 16 views
14

Estoy tratando de incluir un mensaje dinámico en mi anotación que cambie el cuerpo principal del texto en función de los valores que se encuentran en las otras variables que se le pasan. Configuré un mensaje predeterminado, pero cuando se configura un determinado indicador, quiero mostrar un mensaje diferente. es posible?¿Se puede cambiar un mensaje de anotación en tiempo de ejecución?

Aquí es mi anotación -

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

Aquí está la clase de validador utilizado por la anotación -

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

La pieza que más me interesa es el código que lee -

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

¿Por qué intentas hacer esto? Ayudaría a entender lo que está tratando de lograr ... – DNA

+0

Quiero evitar la creación de dos anotaciones para algo que podría lograrse fácilmente con una, además del mensaje diferente. La diferencia entre una anotación a verificar para asegurar que coincidan los campos y para verificar que los campos que no coinciden es muy pequeña. – coder

Respuesta

20

Así es como pude hacer esto -

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

¿Se puede personalizar el "mensaje" solo en el método de inicialización, o puede hacer lo mismo en isValid también? –

Cuestiones relacionadas