2010-03-18 10 views
13

Necesito crear una anotación de restricción personalizada que pueda acceder al valor de otro campo de mi bean. Utilizaré esta anotación para validar el campo porque depende del valor de la otra, pero la forma en que la defino, el compilador dice "El valor para el atributo de anotación" de mi campo "debe ser una expresión constante".Campo de variable en una anotación de restricción

he definido de esta manera:

@Target(ElementType.FIELD) 
@Retention(RetentionPolicy.RUNTIME) 
@Constraint(validatedBy=EqualsFieldValidator.class) 
@Documented 
public @interface EqualsField { 
    public String field(); 

    String message() default "{com.myCom.annotations.EqualsField.message}"; 

    Class<?>[] groups() default {}; 

    Class<? extends Payload>[] payload() default {}; 
} 

public class EqualsFieldValidator implements ConstraintValidator<EqualsField, String>{ 

    private EqualsField equalsField; 

    @Override 
    public void initialize(EqualsField equalsField) { 
     this.equalsField = equalsField;  
    } 

    @Override 
    public boolean isValid(String thisField, ConstraintValidatorContext arg1) { 
     //my validation 
    } 

} 

y en mi frijol Quiero algo como esto:

public class MyBean{ 

    private String field1; 

    @EqualsField(field=field1) 
    private String field2; 
} 

¿Hay alguna manera de definir la anotación por lo que el valor del campo puede ser una variable?

Gracias

+0

Hola, u puede compartir el código de trabajo? Será de gran ayuda. Incluso estoy enfrentando el mismo problema. –

Respuesta

13

Lo más fácil es dar un paso atrás: la restricción/validador que ha escrito funciona a nivel de campo, pero lo que desea aplicar es una dependencia de campo cruzado, es decir, una restricción de nivel de clase.

Vuelva a escribir la restricción y el validador para trabajar en el nivel de clase (es decir, la anotación irá en la clase, no en el campo). De esa forma, tendrás acceso a toda la clase. En su método isValid (..), simplemente haga una obtención en ambos campos, compare y regrese apropiadamente.

+0

Funciona de esta manera, aunque necesito asociar el error de validación con uno de los campos y si valido todo el objeto obtendré un error para todo el objeto en lugar de un error para el campo, pero gracias de todos modos. – Javi

+0

No, ese no es el caso. El segundo argumento del método isValid, ConstraintValidatorContext, le permite anular ese comportamiento. Puede usar el método addError() para decir que el error debería aparecer en un campo específico, así como eliminar el error de nivel de clase predeterminado. – GaryF

0

Como el compilador dijeron anotaciones deben ser constantes (es decir, se puede determinar el valor en tiempo de compilación.) Ahora si estoy adivinando que parece que está utilizando esta anotación para indicar que los valores de esos campos deben ser iguales cuando se ejecuta a través del validador de campo igual. Un enfoque que podría tomar es usar la reflexión. En lugar de tratar de anotar con el valor, anotar con el nombre del campo en lugar

public class MyBean{ 

    private String field1; 

    @EqualsField("field1") 
    private String field2; 
} 

Luego, en el validador se puede leer el nombre del campo y el uso de reflexión para acceder a ella

Object o = object.getClass().getDeclaredField(annotationValue).get(object); 
o == object.(field with annotation) OR 
o.equals(object.(field with annotation)); 

Dependiendo de lo Está tratando de hacerlo, puede que necesite agregar una lógica basada en el tipo de campo, pero sigue siendo el mismo principio general.

+0

OK, pero ¿cómo puedo acceder al objeto donde está la anotación en EqualsFieldValidator? – Javi

+0

No se puede, por desgracia. – GaryF

Cuestiones relacionadas