2012-05-23 14 views
14

Tengo un problema con la anotación @Valid de JSR-303. Los annotation funciona bien para listas o conjuntos y normal, pero estoy tratando de validar los mapas que contienen listas, es decirCómo validar colecciones en Maps

@Valid 
HashMap<String, ArrayList<Object1>> map; 

En este caso, las instancias de la clase Object1 no se validan. ¿Hay una manera conveniente de hacerlo de forma recursiva, sin iterar sobre cada objeto y validarlo manualmente?

Respuesta

13

La especificación no especifica el comportamiento de validación cuando los valores del mapa son listas.

De JSR 303 specification:

Cada objeto proporcionado por el iterador se valida. Para Map, el valor de cada Map.Entry está validado (la clave no está validada).

Dado que el valor en su caso es una lista, que no tiene una anotación @Valid, no se procesa. Para evitar esto, puede:

Ajustar la lista contenida en otro bean, forzando el procesamiento de la anotación en la lista.

public class ListHolder<T extends Iterable> { 
    @Valid 
    public T wrappedList; 
} 

O, alternativamente, se puede escribir un custom validator resuelva sus mapas complejos. Algo como esto:

@Target({ METHOD, FIELD, ANNOTATION_TYPE }) 
@Retention(RUNTIME) 
@Documented 
@Constraint(validatedBy = ValidMapValidator.class) 
public @interface ValidMap { 
    String message() default "valid.map"; 

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

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

public class ValidMapValidator implements 
     ConstraintValidator<ValidMap, Map<?, ?>> { 

    @Override 
    public void initialize(final ValidMap annotation) { 
     return; 
    } 

    @Override 
    public boolean isValid(final Map<?, ?> map, 
     final ConstraintValidatorContext context) { 
     if (map == null || map.size() == 0) 
     return true; 

     // Iterate each map entry and validate 
     return true; 
    } 
} 
+0

Sí, traté de escribir un validador personalizado, pero para validar el objeto real, necesito saber el tipo. Establezca > constraintViolations = validator.validate (car); – liecno

+0

Puede usar comodines para el tipo genérico. Consulte las ediciones de mi respuesta para ver un ejemplo sobre cómo configurar su validador. – Perception