diff --git a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationAdapter.java b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationAdapter.java index c069d96e85..17e320ed06 100644 --- a/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationAdapter.java +++ b/spring-context/src/main/java/org/springframework/validation/beanvalidation/MethodValidationAdapter.java @@ -329,9 +329,12 @@ public class MethodValidationAdapter implements MethodValidator { .addViolation(violation); } else { - // If the argument is a container of elements, we need the specific element, - // but the only option is to check for a parent container index/key in the - // next part of the property path. + + // https://github.com/jakartaee/validation/issues/194 + // If the argument is a container of elements, we need the element, but + // the only option is to see if the next part of the property path has + // a container index/key for its parent and use it. + Path.Node paramNode = node; node = itr.next(); diff --git a/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java b/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java index 8fd02b012f..e21927e331 100644 --- a/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java +++ b/spring-web/src/main/java/org/springframework/web/method/HandlerMethod.java @@ -21,7 +21,6 @@ import java.lang.reflect.AnnotatedParameterizedType; import java.lang.reflect.AnnotatedType; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; @@ -407,8 +406,7 @@ public class HandlerMethod extends AnnotatedMethod { return true; } Class type = param.getParameterType(); - if (merged.stream().anyMatch(VALID_PREDICATE) && - (Collection.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type))) { + if (merged.stream().anyMatch(VALID_PREDICATE) && isIndexOrKeyBasedContainer(type)) { return true; } merged = MergedAnnotations.from(getContainerElementAnnotations(param)); @@ -428,6 +426,15 @@ public class HandlerMethod extends AnnotatedMethod { return false; } + private static boolean isIndexOrKeyBasedContainer(Class type) { + + // Index or key-based containers only, or MethodValidationAdapter cannot access + // the element given what is exposed in ConstraintViolation. + + return (List.class.isAssignableFrom(type) || Object[].class.isAssignableFrom(type) || + Map.class.isAssignableFrom(type)); + } + /** * There may be constraints on elements of a container (list, map). */