PayloadArgumentResolver does not insist on configured Validator anymore
Issue: SPR-12567
(cherry picked from commit ed0e2f4)
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -16,13 +16,15 @@
|
||||
|
||||
package org.springframework.messaging.handler.annotation.support;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.converter.MessageConversionException;
|
||||
import org.springframework.messaging.converter.MessageConverter;
|
||||
import org.springframework.messaging.handler.annotation.Payload;
|
||||
import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver;
|
||||
import org.springframework.messaging.converter.MessageConverter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
@@ -33,15 +35,13 @@ import org.springframework.validation.ObjectError;
|
||||
import org.springframework.validation.SmartValidator;
|
||||
import org.springframework.validation.Validator;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
/**
|
||||
* A resolver to extract and convert the payload of a message using a
|
||||
* {@link MessageConverter}. It also validates the payload using a
|
||||
* {@link Validator} if the argument is annotated with a Validation annotation.
|
||||
*
|
||||
* <p>This {@link HandlerMethodArgumentResolver} should be ordered last as it supports all
|
||||
* types and does not require the {@link Payload} annotation.
|
||||
* <p>This {@link HandlerMethodArgumentResolver} should be ordered last as it
|
||||
* supports all types and does not require the {@link Payload} annotation.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Brian Clozel
|
||||
@@ -55,9 +55,24 @@ public class PayloadArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
private final Validator validator;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@code PayloadArgumentResolver} with the given
|
||||
* {@link MessageConverter}.
|
||||
* @param messageConverter the MessageConverter to use (required)
|
||||
* @since 4.0.9
|
||||
*/
|
||||
public PayloadArgumentResolver(MessageConverter messageConverter) {
|
||||
this(messageConverter, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code PayloadArgumentResolver} with the given
|
||||
* {@link MessageConverter} and {@link Validator}.
|
||||
* @param messageConverter the MessageConverter to use (required)
|
||||
* @param validator the Validator to use (optional)
|
||||
*/
|
||||
public PayloadArgumentResolver(MessageConverter messageConverter, Validator validator) {
|
||||
Assert.notNull(messageConverter, "converter must not be null");
|
||||
Assert.notNull(validator, "validator must not be null");
|
||||
Assert.notNull(messageConverter, "MessageConverter must not be null");
|
||||
this.converter = messageConverter;
|
||||
this.validator = validator;
|
||||
}
|
||||
@@ -70,14 +85,14 @@ public class PayloadArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
|
||||
@Override
|
||||
public Object resolveArgument(MethodParameter param, Message<?> message) throws Exception {
|
||||
Payload annot = param.getParameterAnnotation(Payload.class);
|
||||
if ((annot != null) && StringUtils.hasText(annot.value())) {
|
||||
Payload ann = param.getParameterAnnotation(Payload.class);
|
||||
if (ann != null && StringUtils.hasText(ann.value())) {
|
||||
throw new IllegalStateException("@Payload SpEL expressions not supported by this resolver");
|
||||
}
|
||||
|
||||
Object payload = message.getPayload();
|
||||
if (isEmptyPayload(payload)) {
|
||||
if (annot == null || annot.required()) {
|
||||
if (ann == null || ann.required()) {
|
||||
String paramName = getParameterName(param);
|
||||
BindingResult bindingResult = new BeanPropertyBindingResult(payload, paramName);
|
||||
bindingResult.addError(new ObjectError(paramName, "@Payload param is required"));
|
||||
@@ -106,7 +121,7 @@ public class PayloadArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
|
||||
private String getParameterName(MethodParameter param) {
|
||||
String paramName = param.getParameterName();
|
||||
return (paramName == null ? "Arg " + param.getParameterIndex() : paramName);
|
||||
return (paramName != null ? paramName : "Arg " + param.getParameterIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -132,26 +147,21 @@ public class PayloadArgumentResolver implements HandlerMethodArgumentResolver {
|
||||
if (this.validator == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Annotation annot : parameter.getParameterAnnotations()) {
|
||||
if (annot.annotationType().getSimpleName().startsWith("Valid")) {
|
||||
for (Annotation ann : parameter.getParameterAnnotations()) {
|
||||
if (ann.annotationType().getSimpleName().startsWith("Valid")) {
|
||||
Object hints = AnnotationUtils.getValue(ann);
|
||||
Object[] validationHints = (hints instanceof Object[] ? (Object[]) hints : new Object[] {hints});
|
||||
BeanPropertyBindingResult bindingResult =
|
||||
new BeanPropertyBindingResult(target, getParameterName(parameter));
|
||||
|
||||
Object hints = AnnotationUtils.getValue(annot);
|
||||
Object[] validationHints = (hints instanceof Object[] ? (Object[]) hints : new Object[] {hints});
|
||||
|
||||
if (!ObjectUtils.isEmpty(validationHints) && this.validator instanceof SmartValidator) {
|
||||
((SmartValidator) this.validator).validate(target, bindingResult, validationHints);
|
||||
}
|
||||
else {
|
||||
this.validator.validate(target, bindingResult);
|
||||
}
|
||||
|
||||
if (bindingResult.hasErrors()) {
|
||||
throw new MethodArgumentNotValidException(message, parameter, bindingResult);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@@ -64,7 +64,6 @@ import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.PathMatcher;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.Validator;
|
||||
|
||||
/**
|
||||
@@ -181,7 +180,7 @@ public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHan
|
||||
* The configured Validator instance
|
||||
*/
|
||||
public Validator getValidator() {
|
||||
return validator;
|
||||
return this.validator;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -253,8 +252,7 @@ public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHan
|
||||
resolvers.add(new MessageMethodArgumentResolver());
|
||||
|
||||
resolvers.addAll(getCustomArgumentResolvers());
|
||||
resolvers.add(new PayloadArgumentResolver(this.messageConverter,
|
||||
(this.validator != null ? this.validator : new NoOpValidator())));
|
||||
resolvers.add(new PayloadArgumentResolver(this.messageConverter, this.validator));
|
||||
|
||||
return resolvers;
|
||||
}
|
||||
@@ -284,25 +282,23 @@ public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHan
|
||||
|
||||
@Override
|
||||
protected SimpMessageMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
|
||||
MessageMapping typeAnnot = AnnotationUtils.findAnnotation(handlerType, MessageMapping.class);
|
||||
MessageMapping typeAnnotation = AnnotationUtils.findAnnotation(handlerType, MessageMapping.class);
|
||||
MessageMapping messageAnnot = AnnotationUtils.findAnnotation(method, MessageMapping.class);
|
||||
if (messageAnnot != null) {
|
||||
SimpMessageMappingInfo result = createMessageMappingCondition(messageAnnot);
|
||||
if (typeAnnot != null) {
|
||||
result = createMessageMappingCondition(typeAnnot).combine(result);
|
||||
if (typeAnnotation != null) {
|
||||
result = createMessageMappingCondition(typeAnnotation).combine(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
SubscribeMapping subsribeAnnot = AnnotationUtils.findAnnotation(method, SubscribeMapping.class);
|
||||
if (subsribeAnnot != null) {
|
||||
SimpMessageMappingInfo result = createSubscribeCondition(subsribeAnnot);
|
||||
if (typeAnnot != null) {
|
||||
result = createMessageMappingCondition(typeAnnot).combine(result);
|
||||
SubscribeMapping subsribeAnnotation = AnnotationUtils.findAnnotation(method, SubscribeMapping.class);
|
||||
if (subsribeAnnotation != null) {
|
||||
SimpMessageMappingInfo result = createSubscribeCondition(subsribeAnnotation);
|
||||
if (typeAnnotation != null) {
|
||||
result = createMessageMappingCondition(typeAnnotation).combine(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -368,17 +364,4 @@ public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHan
|
||||
return new AnnotationExceptionHandlerMethodResolver(beanType);
|
||||
}
|
||||
|
||||
|
||||
private static final class NoOpValidator implements Validator {
|
||||
|
||||
@Override
|
||||
public boolean supports(Class<?> clazz) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validate(Object target, Errors errors) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user