2012-05-04 5 views
6

Ho un fagiolo semplice con enum campoJSR-303 Bean Validation per i campi enum

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

enum TestEnum{ 
    A, B, C, D 
} 

Vorrei validare testField utilizzando Bean Validation. In particolare vorrei assicurarsi che siano ammessi solo i valori A e B (per un particolare gropus di calidazione). Sembra che le enumerazioni non siano gestite da JSR 303 (stavo cercando di usare il validatore @Pattern) o sto facendo qualcosa in modo sbagliato.

io sono sempre un'eccezione:

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

Esiste un modo per convalidare i campi enum senza scrivere di convalida personalizzata?

risposta

3

Se si desidera applicare il vincolo a testField, è necessario un validatore personalizzato. Nessuno di quelli predefiniti gestisce le enumerazioni.

Per risolvere il problema si potrebbe aggiungere un metodo getter che restituisce il valore stringa della enum

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

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

Un validatore personalizzato è probabilmente la soluzione più pulita però.

3

Poiché per alcune ragioni non sono supportate le enumerazioni questa restrizione potrebbe essere semplicemente gestita da un semplice Validatore basato su Stringhe.

Validator:

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

Interfaccia:

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

Validator utilizza la libreria Commons apache. Un metodo avanzato di tipo "coerce to type" migliorerebbe ulteriormente la flessibilità di questo validatore.

Un'alternativa potrebbe utilizzare un singolo attributo String invece di un array e diviso in delimitatore. Ciò anche stampare i valori correttamente per messaggio di errore poiché gli array non vengono stampati, ma la gestione di valori nulli potrebbe essere un problema utilizzando String.valueOf(...)