Support method validation for Lists in WebMvc and WebFlux

Closes gh-31120
This commit is contained in:
rstoyanchev
2023-09-04 13:21:59 +01:00
parent 6597727c86
commit b068742ec8
5 changed files with 120 additions and 16 deletions

View File

@@ -18,6 +18,7 @@ package org.springframework.web.method;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.List;
import java.util.StringJoiner;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -383,19 +384,25 @@ public class HandlerMethod extends AnnotatedMethod {
*/
private static class MethodValidationInitializer {
private static final Predicate<MergedAnnotation<? extends Annotation>> INPUT_PREDICATE =
private static final Predicate<MergedAnnotation<? extends Annotation>> CONSTRAINT_PREDICATE =
MergedAnnotationPredicates.typeIn("jakarta.validation.Constraint");
private static final Predicate<MergedAnnotation<? extends Annotation>> OUTPUT_PREDICATE =
MergedAnnotationPredicates.typeIn("jakarta.validation.Valid", "jakarta.validation.Constraint");
private static final Predicate<MergedAnnotation<? extends Annotation>> VALID_PREDICATE =
MergedAnnotationPredicates.typeIn("jakarta.validation.Valid");
public static boolean checkArguments(Class<?> beanType, MethodParameter[] parameters) {
if (AnnotationUtils.findAnnotation(beanType, Validated.class) == null) {
for (MethodParameter parameter : parameters) {
MergedAnnotations merged = MergedAnnotations.from(parameter.getParameterAnnotations());
if (merged.stream().anyMatch(INPUT_PREDICATE)) {
if (merged.stream().anyMatch(CONSTRAINT_PREDICATE)) {
return true;
}
else {
Class<?> type = parameter.getParameterType();
if (merged.stream().anyMatch(VALID_PREDICATE) && List.class.isAssignableFrom(type)) {
return true;
}
}
}
}
return false;
@@ -404,7 +411,7 @@ public class HandlerMethod extends AnnotatedMethod {
public static boolean checkReturnValue(Class<?> beanType, Method method) {
if (AnnotationUtils.findAnnotation(beanType, Validated.class) == null) {
MergedAnnotations merged = MergedAnnotations.from(method, MergedAnnotations.SearchStrategy.TYPE_HIERARCHY);
return merged.stream().anyMatch(OUTPUT_PREDICATE);
return merged.stream().anyMatch(CONSTRAINT_PREDICATE.or(VALID_PREDICATE));
}
return false;
}