diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolver.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolver.java index 218ec1cf9dc..ce45891800a 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolver.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolver.java @@ -72,7 +72,7 @@ public class MessageMethodArgumentResolver implements HandlerMethodArgumentResol @Override public Object resolveArgument(MethodParameter parameter, Message message) throws Exception { Class targetMessageType = parameter.getParameterType(); - Class targetPayloadType = getPayloadType(parameter); + Class targetPayloadType = getPayloadType(parameter, message); if (!targetMessageType.isAssignableFrom(message.getClass())) { throw new MethodArgumentTypeMismatchException(message, parameter, "Actual message type '" + @@ -95,7 +95,19 @@ public class MessageMethodArgumentResolver implements HandlerMethodArgumentResol return MessageBuilder.createMessage(payload, message.getHeaders()); } - private Class getPayloadType(MethodParameter parameter) { + /** + * Resolve the target class to convert the payload to. + *

By default this is the generic type declared in the {@code Message} + * method parameter but that can be overridden to select a more specific + * target type after also taking into account the "Content-Type", e.g. + * return {@code String} if target type is {@code Object} and + * {@code "Content-Type:text/**"}. + * @param parameter the target method parameter + * @param message the message bring processed + * @return the target type to use + * @since 5.2 + */ + protected Class getPayloadType(MethodParameter parameter, Message message) { Type genericParamType = parameter.getGenericParameterType(); ResolvableType resolvableType = ResolvableType.forType(genericParamType).as(Message.class); return resolvableType.getGeneric().toClass(); diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/PayloadMethodArgumentResolver.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/PayloadMethodArgumentResolver.java index f3bc844db98..697db66131d 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/PayloadMethodArgumentResolver.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/annotation/support/PayloadMethodArgumentResolver.java @@ -126,7 +126,7 @@ public class PayloadMethodArgumentResolver implements HandlerMethodArgumentResol } } - Class targetClass = parameter.getParameterType(); + Class targetClass = resolveTargetClass(parameter, message); Class payloadClass = payload.getClass(); if (ClassUtils.isAssignable(targetClass, payloadClass)) { validate(message, parameter, payload); @@ -173,6 +173,21 @@ public class PayloadMethodArgumentResolver implements HandlerMethodArgumentResol } } + /** + * Resolve the target class to convert the payload to. + *

By default this is simply {@link MethodParameter#getParameterType()} + * but that can be overridden to select a more specific target type after + * also taking into account the "Content-Type", e.g. return {@code String} + * if target type is {@code Object} and {@code "Content-Type:text/**"}. + * @param parameter the target method parameter + * @param message the message bring processed + * @return the target type to use + * @since 5.2 + */ + protected Class resolveTargetClass(MethodParameter parameter, Message message) { + return parameter.getParameterType(); + } + /** * Validate the payload if applicable. *

The default implementation checks for {@code @javax.validation.Valid},