Skip to content

Commit 86a101a

Browse files
committed
Merge branch '6.0.x'
2 parents 1f544f1 + c7269fe commit 86a101a

File tree

4 files changed

+37
-32
lines changed

4 files changed

+37
-32
lines changed

spring-context/src/main/java/org/springframework/validation/annotation/ValidationAnnotationUtils.java

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,37 +26,46 @@
2626
* Mainly for internal use within the framework.
2727
*
2828
* @author Christoph Dreis
29+
* @author Juergen Hoeller
2930
* @since 5.3.7
3031
*/
3132
public abstract class ValidationAnnotationUtils {
3233

3334
private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
3435

36+
3537
/**
3638
* Determine any validation hints by the given annotation.
37-
* <p>This implementation checks for {@code @jakarta.validation.Valid},
38-
* Spring's {@link org.springframework.validation.annotation.Validated},
39-
* and custom annotations whose name starts with "Valid".
39+
* <p>This implementation checks for Spring's
40+
* {@link org.springframework.validation.annotation.Validated},
41+
* {@code @jakarta.validation.Valid}, and custom annotations whose
42+
* name starts with "Valid" which may optionally declare validation
43+
* hints through the "value" attribute.
4044
* @param ann the annotation (potentially a validation annotation)
4145
* @return the validation hints to apply (possibly an empty array),
4246
* or {@code null} if this annotation does not trigger any validation
4347
*/
4448
@Nullable
4549
public static Object[] determineValidationHints(Annotation ann) {
50+
// Direct presence of @Validated ?
51+
if (ann instanceof Validated validated) {
52+
return validated.value();
53+
}
54+
// Direct presence of @Valid ?
4655
Class<? extends Annotation> annotationType = ann.annotationType();
47-
String annotationName = annotationType.getName();
48-
if ("jakarta.validation.Valid".equals(annotationName)) {
56+
if ("jakarta.validation.Valid".equals(annotationType.getName())) {
4957
return EMPTY_OBJECT_ARRAY;
5058
}
59+
// Meta presence of @Validated ?
5160
Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class);
5261
if (validatedAnn != null) {
53-
Object hints = validatedAnn.value();
54-
return convertValidationHints(hints);
62+
return validatedAnn.value();
5563
}
64+
// Custom validation annotation ?
5665
if (annotationType.getSimpleName().startsWith("Valid")) {
57-
Object hints = AnnotationUtils.getValue(ann);
58-
return convertValidationHints(hints);
66+
return convertValidationHints(AnnotationUtils.getValue(ann));
5967
}
68+
// No validation triggered
6069
return null;
6170
}
6271

spring-core/src/main/java/org/springframework/core/annotation/AnnotationUtils.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,8 +1309,8 @@ static Annotation[] synthesizeAnnotationArray(Annotation[] annotations, Annotate
13091309
*/
13101310
public static boolean isSynthesizedAnnotation(@Nullable Annotation annotation) {
13111311
try {
1312-
return ((annotation != null) && Proxy.isProxyClass(annotation.getClass()) &&
1313-
(Proxy.getInvocationHandler(annotation) instanceof SynthesizedMergedAnnotationInvocationHandler));
1312+
return (annotation != null && Proxy.isProxyClass(annotation.getClass()) &&
1313+
Proxy.getInvocationHandler(annotation) instanceof SynthesizedMergedAnnotationInvocationHandler);
13141314
}
13151315
catch (SecurityException ex) {
13161316
// Security settings disallow reflective access to the InvocationHandler:

spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/reactive/PayloadMethodArgumentResolver.java

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import org.springframework.core.ReactiveAdapter;
3434
import org.springframework.core.ReactiveAdapterRegistry;
3535
import org.springframework.core.ResolvableType;
36-
import org.springframework.core.annotation.AnnotationUtils;
3736
import org.springframework.core.codec.Decoder;
3837
import org.springframework.core.codec.DecodingException;
3938
import org.springframework.core.io.buffer.DataBuffer;
@@ -54,17 +53,17 @@
5453
import org.springframework.validation.BeanPropertyBindingResult;
5554
import org.springframework.validation.SmartValidator;
5655
import org.springframework.validation.Validator;
57-
import org.springframework.validation.annotation.Validated;
56+
import org.springframework.validation.annotation.ValidationAnnotationUtils;
5857

5958
/**
6059
* A resolver to extract and decode the payload of a message using a
61-
* {@link Decoder}, where the payload is expected to be a {@link Publisher} of
62-
* {@link DataBuffer DataBuffer}.
60+
* {@link Decoder}, where the payload is expected to be a {@link Publisher}
61+
* of {@link DataBuffer DataBuffer}.
6362
*
6463
* <p>Validation is applied if the method argument is annotated with
65-
* {@code @jakarta.validation.Valid} or
66-
* {@link org.springframework.validation.annotation.Validated}. Validation
67-
* failure results in an {@link MethodArgumentNotValidException}.
64+
* {@link org.springframework.validation.annotation.Validated} or
65+
* {@code @jakarta.validation.Valid}. Validation failure results in an
66+
* {@link MethodArgumentNotValidException}.
6867
*
6968
* <p>This resolver should be ordered last if {@link #useDefaultResolution} is
7069
* set to {@code true} since in that case it supports all types and does not
@@ -286,10 +285,8 @@ private Consumer<Object> getValidator(Message<?> message, MethodParameter parame
286285
return null;
287286
}
288287
for (Annotation ann : parameter.getParameterAnnotations()) {
289-
Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class);
290-
if (validatedAnn != null || ann.annotationType().getSimpleName().startsWith("Valid")) {
291-
Object hints = (validatedAnn != null ? validatedAnn.value() : AnnotationUtils.getValue(ann));
292-
Object[] validationHints = (hints instanceof Object[] objectHints ? objectHints : new Object[] {hints});
288+
Object[] validationHints = ValidationAnnotationUtils.determineValidationHints(ann);
289+
if (validationHints != null) {
293290
String name = Conventions.getVariableNameForParameter(parameter);
294291
return target -> {
295292
BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(target, name);

spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/PayloadMethodArgumentResolver.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import java.util.Optional;
2121

2222
import org.springframework.core.MethodParameter;
23-
import org.springframework.core.annotation.AnnotationUtils;
2423
import org.springframework.lang.Nullable;
2524
import org.springframework.messaging.Message;
2625
import org.springframework.messaging.converter.MessageConversionException;
@@ -38,12 +37,16 @@
3837
import org.springframework.validation.ObjectError;
3938
import org.springframework.validation.SmartValidator;
4039
import org.springframework.validation.Validator;
41-
import org.springframework.validation.annotation.Validated;
40+
import org.springframework.validation.annotation.ValidationAnnotationUtils;
4241

4342
/**
4443
* A resolver to extract and convert the payload of a message using a
45-
* {@link MessageConverter}. It also validates the payload using a
46-
* {@link Validator} if the argument is annotated with a Validation annotation.
44+
* {@link MessageConverter}.
45+
*
46+
* <p>Validation is applied if the method argument is annotated with
47+
* {@link org.springframework.validation.annotation.Validated} or
48+
* {@code @jakarta.validation.Valid}. Validation failure results in an
49+
* {@link MethodArgumentNotValidException}.
4750
*
4851
* <p>This {@link HandlerMethodArgumentResolver} should be ordered last as it
4952
* supports all types and does not require the {@link Payload} annotation.
@@ -196,8 +199,6 @@ protected Class<?> resolveTargetClass(MethodParameter parameter, Message<?> mess
196199

197200
/**
198201
* Validate the payload if applicable.
199-
* <p>The default implementation checks for {@code @jakarta.validation.Valid},
200-
* Spring's {@link Validated}, and custom annotations whose name starts with "Valid".
201202
* @param message the currently processed message
202203
* @param parameter the method parameter
203204
* @param target the target payload object
@@ -208,10 +209,8 @@ protected void validate(Message<?> message, MethodParameter parameter, Object ta
208209
return;
209210
}
210211
for (Annotation ann : parameter.getParameterAnnotations()) {
211-
Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class);
212-
if (validatedAnn != null || ann.annotationType().getSimpleName().startsWith("Valid")) {
213-
Object hints = (validatedAnn != null ? validatedAnn.value() : AnnotationUtils.getValue(ann));
214-
Object[] validationHints = (hints instanceof Object[] objectHints ? objectHints : new Object[] {hints});
212+
Object[] validationHints = ValidationAnnotationUtils.determineValidationHints(ann);
213+
if (validationHints != null) {
215214
BeanPropertyBindingResult bindingResult =
216215
new BeanPropertyBindingResult(target, getParameterName(parameter));
217216
if (!ObjectUtils.isEmpty(validationHints) && this.validator instanceof SmartValidator sv) {

0 commit comments

Comments
 (0)