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 03b9ba0681..a388946ffb 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 @@ -26,7 +26,6 @@ import org.springframework.messaging.converter.MessageConverter; import org.springframework.messaging.converter.SmartMessageConverter; import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver; import org.springframework.messaging.support.MessageBuilder; -import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.StringUtils; @@ -38,6 +37,7 @@ import org.springframework.util.StringUtils; * * @author Rossen Stoyanchev * @author Stephane Nicoll + * @author Juergen Hoeller * @since 4.0 */ public class MessageMethodArgumentResolver implements HandlerMethodArgumentResolver { @@ -46,12 +46,18 @@ public class MessageMethodArgumentResolver implements HandlerMethodArgumentResol /** - * Create a new instance with the given {@link MessageConverter}. - * @param converter the MessageConverter to use (required) - * @since 4.1 + * Create a default resolver instance without message conversion. + */ + public MessageMethodArgumentResolver() { + this(null); + } + + /** + * Create a resolver instance with the given {@link MessageConverter}. + * @param converter the MessageConverter to use (may be {@code null}) + * @since 4.3 */ public MessageMethodArgumentResolver(MessageConverter converter) { - Assert.notNull(converter, "MessageConverter must not be null"); this.converter = converter; } @@ -63,7 +69,6 @@ public class MessageMethodArgumentResolver implements HandlerMethodArgumentResol @Override public Object resolveArgument(MethodParameter parameter, Message message) throws Exception { - Class targetMessageType = parameter.getParameterType(); Class targetPayloadType = getPayloadType(parameter); @@ -117,20 +122,20 @@ public class MessageMethodArgumentResolver implements HandlerMethodArgumentResol } private Object convertPayload(Message message, MethodParameter parameter, Class targetPayloadType) { - Object result; + Object result = null; if (this.converter instanceof SmartMessageConverter) { SmartMessageConverter smartConverter = (SmartMessageConverter) this.converter; result = smartConverter.fromMessage(message, targetPayloadType, parameter); } - else { + else if (this.converter != null) { result = this.converter.fromMessage(message, targetPayloadType); } if (result == null) { String actual = ClassUtils.getQualifiedName(targetPayloadType); String expected = ClassUtils.getQualifiedName(message.getPayload().getClass()); - throw new MessageConversionException(message, "No converter found to convert payload " + - "type [" + actual + "] to expected payload type [" + expected + "]."); + throw new MessageConversionException(message, "No converter found to convert payload type [" + + actual + "] to expected payload type [" + expected + "]"); } return result; } diff --git a/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolverTests.java b/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolverTests.java index 159207c18a..792910f7b4 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolverTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/handler/annotation/support/MessageMethodArgumentResolverTests.java @@ -33,14 +33,13 @@ import org.springframework.messaging.support.GenericMessage; import org.springframework.messaging.support.MessageBuilder; import static org.junit.Assert.*; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; +import static org.mockito.Mockito.*; /** - * Unit tests for - * {@link org.springframework.messaging.handler.annotation.support.MessageMethodArgumentResolver}. + * Unit tests for {@link MessageMethodArgumentResolver}. * * @author Stephane Nicoll + * @author Juergen Hoeller */ public class MessageMethodArgumentResolverTests { @@ -56,10 +55,8 @@ public class MessageMethodArgumentResolverTests { @Before public void setup() throws Exception { - this.method = MessageMethodArgumentResolverTests.class.getDeclaredMethod("handle", - Message.class, Message.class, Message.class, Message.class, - ErrorMessage.class); + Message.class, Message.class, Message.class, Message.class, ErrorMessage.class); this.converter = mock(MessageConverter.class); this.resolver = new MessageMethodArgumentResolver(this.converter); @@ -85,7 +82,7 @@ public class MessageMethodArgumentResolverTests { } @Test - public void resolveWithPayloadTypeSubClass() throws Exception { + public void resolveWithPayloadTypeSubclass() throws Exception { Message message = MessageBuilder.withPayload(123).build(); MethodParameter parameter = new MethodParameter(this.method, 2); @@ -155,7 +152,7 @@ public class MessageMethodArgumentResolverTests { } @Test - public void resolveMessageSubClassMatch() throws Exception { + public void resolveMessageSubclassMatch() throws Exception { ErrorMessage message = new ErrorMessage(new UnsupportedOperationException()); MethodParameter parameter = new MethodParameter(this.method, 4); @@ -164,7 +161,7 @@ public class MessageMethodArgumentResolverTests { } @Test - public void resolveWithMessageSubClassAndPayloadWildcard() throws Exception { + public void resolveWithMessageSubclassAndPayloadWildcard() throws Exception { ErrorMessage message = new ErrorMessage(new UnsupportedOperationException()); MethodParameter parameter = new MethodParameter(this.method, 0); @@ -185,6 +182,46 @@ public class MessageMethodArgumentResolverTests { assertSame(message, this.resolver.resolveArgument(parameter, message)); } + @Test + public void resolveWithPayloadTypeAsWildcardAndNoConverter() throws Exception { + this.resolver = new MessageMethodArgumentResolver(); + + Message message = MessageBuilder.withPayload("test").build(); + MethodParameter parameter = new MethodParameter(this.method, 0); + + assertTrue(this.resolver.supportsParameter(parameter)); + assertSame(message, this.resolver.resolveArgument(parameter, message)); + } + + @Test + public void resolveWithConversionNeededButNoConverter() throws Exception { + this.resolver = new MessageMethodArgumentResolver(); + + Message message = MessageBuilder.withPayload("test").build(); + MethodParameter parameter = new MethodParameter(this.method, 1); + + assertTrue(this.resolver.supportsParameter(parameter)); + thrown.expect(MessageConversionException.class); + thrown.expectMessage(Integer.class.getName()); + thrown.expectMessage(String.class.getName()); + this.resolver.resolveArgument(parameter, message); + } + + @Test + public void resolveWithConversionEmptyPayloadButNoConverter() throws Exception { + this.resolver = new MessageMethodArgumentResolver(); + + Message message = MessageBuilder.withPayload("").build(); + MethodParameter parameter = new MethodParameter(this.method, 1); + + assertTrue(this.resolver.supportsParameter(parameter)); + thrown.expect(MessageConversionException.class); + thrown.expectMessage("the payload is empty"); + thrown.expectMessage(Integer.class.getName()); + thrown.expectMessage(String.class.getName()); + this.resolver.resolveArgument(parameter, message); + } + @SuppressWarnings("unused") private void handle(