2012-05-04 18 views
6

que tienen un grano sencillo con enum campoJSR-303 Bean Validation para los campos de enumeración

public class TestBean{ 
    @Pattern(regexp = "A|B") //does not work 
    private TestEnum testField; 
    //getters + setters 
} 

enum TestEnum{ 
    A, B, C, D 
} 

me gustaría validar testField usando Bean Validation. Específicamente, me gustaría asegurarme de que solo se permiten los valores A y B (para un gropus de calidación particular). Parece que las enumeraciones no se manejan en JSR 303 (estaba intentando usar el validador @Pattern) o estoy haciendo algo de una manera incorrecta.

Me estoy haciendo una excepción:

javax.validation.UnexpectedTypeException: No validator could be found for type: packagename.TestEnum 

¿Hay alguna manera de validar campos de enumeración sin escribir validador personalizado?

Respuesta

3

Si quiere poner la restricción en testField, necesita un validador personalizado. Ninguno de los predeterminados maneja las enumeraciones.

Como solución alternativa se podría añadir un método getter que devuelve el valor de cadena de la enumeración

public class TestBean{ 
    private TestEnum testField; 
    //getters + setters 

    @Pattern(regexp = "A|B") //does not work 
    private String getTestFieldName() { 
     return testField.name(); 
    } 
} 

Un validador personalizado es probablemente la solución más limpia aunque.

3

Dado que por algunas razones las enumeraciones no son compatibles, esta restricción podría ser manejada simplemente por un simple Validador basado en cadenas.

Validador:

/** 
* Validates a given object's String representation to match one of the provided 
* values. 
*/ 
public class ValueValidator implements ConstraintValidator<Value, Object> 
{ 
    /** 
    * String array of possible enum values 
    */ 
    private String[] values; 

    @Override 
    public void initialize(final Value constraintAnnotation) 
    { 
     this.values = constraintAnnotation.values(); 
    } 

    @Override 
    public boolean isValid(final Object value, final ConstraintValidatorContext context) 
    { 
     return ArrayUtils.contains(this.values, value == null ? null : value.toString()); 
    } 
} 

Interfaz:

@Target(value = 
{ 
    ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER 
}) 
@Retention(RetentionPolicy.RUNTIME) 
@Constraint(validatedBy = 
{ 
    ValueValidator.class 
}) 
@Documented 
public @interface Value 
{ 
    public String message() default "{package.Value.message}"; 

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

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

    public String[] values() default 
    {}; 
} 

Validador utiliza la biblioteca apache commons. Un método de coerción avanzada a tipo mejoraría aún más la flexibilidad de este validador.

Una alternativa podría usar un solo atributo de cadena en lugar de una matriz y dividir por delimitador. Esto también imprimiría valores muy bien para mensaje de error ya que las matrices no se están imprimiendo, pero manejar valores nulos podría ser un problema usando String.valueOf(...)

Cuestiones relacionadas