diff --git a/spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java b/spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java index 35f8aa16c2..eb725fc3ce 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/converter/MappingJackson2MessageConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,7 +39,6 @@ import com.fasterxml.jackson.databind.SerializationFeature; import org.springframework.core.GenericTypeResolver; import org.springframework.core.MethodParameter; -import org.springframework.core.ResolvableType; import org.springframework.lang.Nullable; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHeaders; @@ -240,6 +239,9 @@ public class MappingJackson2MessageConverter extends AbstractMessageConverter { if (conversionHint instanceof MethodParameter) { MethodParameter param = (MethodParameter) conversionHint; param = param.nestedIfOptional(); + if (Message.class.isAssignableFrom(param.getParameterType())) { + param = param.nested(); + } Type genericParameterType = param.getNestedGenericParameterType(); Class contextClass = param.getContainingClass(); Type type = GenericTypeResolver.resolveType(genericParameterType, contextClass); diff --git a/spring-messaging/src/test/java/org/springframework/messaging/converter/MappingJackson2MessageConverterTests.java b/spring-messaging/src/test/java/org/springframework/messaging/converter/MappingJackson2MessageConverterTests.java index e882dad7dd..17183f3a21 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/converter/MappingJackson2MessageConverterTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/converter/MappingJackson2MessageConverterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,7 +46,7 @@ import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; /** - * Test fixture for {@link org.springframework.messaging.converter.MappingJackson2MessageConverter}. + * Test fixture for {@link MappingJackson2MessageConverter}. * * @author Rossen Stoyanchev * @author Sebastien Deleuze @@ -150,6 +150,20 @@ public class MappingJackson2MessageConverterTests { assertEquals(Arrays.asList(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L), actual); } + @Test // SPR-16486 + public void fromMessageToMessageWithPojo() throws Exception { + MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(); + String payload = "{\"string\":\"foo\"}"; + Message message = MessageBuilder.withPayload(payload.getBytes(StandardCharsets.UTF_8)).build(); + + Method method = getClass().getDeclaredMethod("handleMessage", Message.class); + MethodParameter param = new MethodParameter(method, 0); + Object actual = converter.fromMessage(message, Message.class, param); + + assertTrue(actual instanceof MyBean); + assertEquals("foo", ((MyBean) actual).getString()); + } + @Test public void toMessage() throws Exception { MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter(); @@ -242,6 +256,7 @@ public class MappingJackson2MessageConverterTests { void handleList(List payload) {} + void handleMessage(Message message) {} public static class MyBean { 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 a7cb5507cc..4d095353c4 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2018 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,6 +26,7 @@ import org.junit.rules.ExpectedException; import org.springframework.core.MethodParameter; import org.springframework.messaging.Message; +import org.springframework.messaging.converter.MappingJackson2MessageConverter; import org.springframework.messaging.converter.MessageConversionException; import org.springframework.messaging.converter.MessageConverter; import org.springframework.messaging.support.ErrorMessage; @@ -56,7 +57,7 @@ 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, Message.class); this.converter = mock(MessageConverter.class); this.resolver = new MessageMethodArgumentResolver(this.converter); @@ -222,6 +223,20 @@ public class MessageMethodArgumentResolverTests { this.resolver.resolveArgument(parameter, message); } + @Test // SPR-16486 + public void resolveWithJacksonConverter() throws Exception { + Message inMessage = MessageBuilder.withPayload("{\"foo\":\"bar\"}").build(); + MethodParameter parameter = new MethodParameter(this.method, 5); + + this.resolver = new MessageMethodArgumentResolver(new MappingJackson2MessageConverter()); + Object actual = this.resolver.resolveArgument(parameter, inMessage); + + assertTrue(actual instanceof Message); + Message outMessage = (Message) actual; + assertTrue(outMessage.getPayload() instanceof Foo); + assertEquals("bar", ((Foo) outMessage.getPayload()).getFoo()); + } + @SuppressWarnings("unused") private void handle( @@ -229,7 +244,23 @@ public class MessageMethodArgumentResolverTests { Message integerPayload, Message numberPayload, Message anyNumberPayload, - ErrorMessage subClass) { + ErrorMessage subClass, + Message fooPayload) { + } + + + static class Foo { + + private String foo; + + public String getFoo() { + return foo; + } + + public void setFoo(String foo) { + this.foo = foo; + } + } }