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},