Как проверить коллекцию на картах

У меня проблема с аннотацией @Valid JSR-303. аннотация отлично подходит для обычных списков и/или наборов, но я пытаюсь проверить Карты, содержащие списки, т.е.

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

В этом случае экземпляры класса Object1 не проверяются. Есть ли удобный способ сделать это рекурсивно, без повторения каждого объекта и проверки его вручную?

Ответы

Ответ 1

В спецификации не указывается поведение валидации, когда сами значения карт перечислены.

Из Спецификация JSR 303:

Каждый объект, предоставленный итератором, проверяется. Для Карты значение каждой Map.Entry проверяется (ключ не проверяется).

Поскольку значение в вашем случае представляет собой список, который не имеет аннотации @Valid, он не обрабатывается. Чтобы обойти это, вы можете:

Оберните содержащийся список в другой bean, заставив обработку аннотации в список.

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

Или вы можете написать настраиваемый валидатор для обработки сложных карт. Что-то вроде этого:

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