PayloadArgumentResolver supports JsonView as well (through AbstractMessageConverter revision)

AbstractMessageConverter provides overloaded methods with a conversion hint, MappingJackson2MessageConverter takes that hint into account, and SimpMessagingTemplate transformes such a hint in the given headers map into an explicit argument invocation argument.

Issue: SPR-13265
This commit is contained in:
Juergen Hoeller
2015-07-24 17:50:31 +02:00
parent 24b1dc14d2
commit 0f54f686b2
12 changed files with 216 additions and 115 deletions

View File

@@ -74,8 +74,7 @@ public class MappingJackson2MessageConverterTests {
@Test
public void fromMessage() throws Exception {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
String payload = "{\"bytes\":\"AQI=\",\"array\":[\"Foo\",\"Bar\"],"
+ "\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}";
String payload = "{\"bytes\":\"AQI=\",\"array\":[\"Foo\",\"Bar\"],\"number\":42,\"string\":\"Foo\",\"bool\":true,\"fraction\":42.0}";
Message<?> message = MessageBuilder.withPayload(payload.getBytes(UTF_8)).build();
MyBean actual = (MyBean) converter.fromMessage(message, MyBean.class);
@@ -178,20 +177,25 @@ public class MappingJackson2MessageConverterTests {
}
@Test
public void jsonView() throws Exception {
public void toMessageJsonView() throws Exception {
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
Map<String, Object> map = new HashMap<>();
Method method = this.getClass().getDeclaredMethod("handle");
Method method = getClass().getDeclaredMethod("jsonViewResponse");
MethodParameter returnType = new MethodParameter(method, -1);
map.put(AbstractMessageConverter.METHOD_PARAMETER_HINT_HEADER, returnType);
MessageHeaders headers = new MessageHeaders(map);
Message<?> message = converter.toMessage(handle(), headers);
Message<?> message = converter.toMessage(jsonViewResponse(), new MessageHeaders(map), returnType);
String actual = new String((byte[]) message.getPayload(), UTF_8);
assertThat(actual, containsString("\"withView1\":\"with\""));
assertThat(actual, not(containsString("\"withView2\":\"with\"")));
assertThat(actual, not(containsString("\"withoutView\":\"without\"")));
assertThat(actual, containsString("\"withView2\":\"with\""));
assertThat(actual, not(containsString("\"withoutView\":\"with\"")));
method = getClass().getDeclaredMethod("jsonViewPayload", JacksonViewBean.class);
MethodParameter param = new MethodParameter(method, 0);
JacksonViewBean back = (JacksonViewBean) converter.fromMessage(message, JacksonViewBean.class, param);
assertNull(back.getWithView1());
assertEquals("with", back.getWithView2());
assertNull(back.getWithoutView());
}
@@ -266,7 +270,7 @@ public class MappingJackson2MessageConverterTests {
@JsonView(MyJacksonView1.class)
private String withView1;
@JsonView(MyJacksonView2.class)
@JsonView({MyJacksonView1.class, MyJacksonView2.class})
private String withView2;
private String withoutView;
@@ -297,12 +301,15 @@ public class MappingJackson2MessageConverterTests {
}
@JsonView(MyJacksonView1.class)
public JacksonViewBean handle() {
public JacksonViewBean jsonViewResponse() {
JacksonViewBean bean = new JacksonViewBean();
bean.setWithView1("with");
bean.setWithView2("with");
bean.setWithoutView("without");
bean.setWithoutView("with");
return bean;
}
public void jsonViewPayload(@JsonView(MyJacksonView2.class) JacksonViewBean payload) {
}
}

View File

@@ -38,7 +38,6 @@ import org.springframework.core.annotation.SynthesizingMethodParameter;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.converter.AbstractMessageConverter;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.converter.StringMessageConverter;
import org.springframework.messaging.handler.DestinationPatternsMessageCondition;
@@ -143,7 +142,6 @@ public class SendToMethodReturnValueHandlerTests {
@Test
public void sendToNoAnnotations() throws Exception {
given(this.messageChannel.send(any(Message.class))).willReturn(true);
Message<?> inputMessage = createInputMessage("sess1", "sub1", "/app", "/dest", null);
@@ -156,12 +154,11 @@ public class SendToMethodReturnValueHandlerTests {
assertEquals("/topic/dest", accessor.getDestination());
assertEquals(MIME_TYPE, accessor.getContentType());
assertNull("Subscription id should not be copied", accessor.getSubscriptionId());
assertEquals(this.noAnnotationsReturnType, accessor.getHeader(AbstractMessageConverter.METHOD_PARAMETER_HINT_HEADER));
assertEquals(this.noAnnotationsReturnType, accessor.getHeader(SimpMessagingTemplate.CONVERSION_HINT_HEADER));
}
@Test
public void sendTo() throws Exception {
given(this.messageChannel.send(any(Message.class))).willReturn(true);
String sessionId = "sess1";
@@ -175,19 +172,18 @@ public class SendToMethodReturnValueHandlerTests {
assertEquals("/dest1", accessor.getDestination());
assertEquals(MIME_TYPE, accessor.getContentType());
assertNull("Subscription id should not be copied", accessor.getSubscriptionId());
assertEquals(this.sendToReturnType, accessor.getHeader(AbstractMessageConverter.METHOD_PARAMETER_HINT_HEADER));
assertEquals(this.sendToReturnType, accessor.getHeader(SimpMessagingTemplate.CONVERSION_HINT_HEADER));
accessor = getCapturedAccessor(1);
assertEquals(sessionId, accessor.getSessionId());
assertEquals("/dest2", accessor.getDestination());
assertEquals(MIME_TYPE, accessor.getContentType());
assertNull("Subscription id should not be copied", accessor.getSubscriptionId());
assertEquals(this.sendToReturnType, accessor.getHeader(AbstractMessageConverter.METHOD_PARAMETER_HINT_HEADER));
assertEquals(this.sendToReturnType, accessor.getHeader(SimpMessagingTemplate.CONVERSION_HINT_HEADER));
}
@Test
public void sendToDefaultDestination() throws Exception {
given(this.messageChannel.send(any(Message.class))).willReturn(true);
String sessionId = "sess1";
@@ -201,12 +197,11 @@ public class SendToMethodReturnValueHandlerTests {
assertEquals("/topic/dest", accessor.getDestination());
assertEquals(MIME_TYPE, accessor.getContentType());
assertNull("Subscription id should not be copied", accessor.getSubscriptionId());
assertEquals(this.sendToDefaultDestReturnType, accessor.getHeader(AbstractMessageConverter.METHOD_PARAMETER_HINT_HEADER));
assertEquals(this.sendToDefaultDestReturnType, accessor.getHeader(SimpMessagingTemplate.CONVERSION_HINT_HEADER));
}
@Test
public void sendToDefaultDestinationWhenUsingDotPathSeparator() throws Exception {
given(this.messageChannel.send(any(Message.class))).willReturn(true);
Message<?> inputMessage = createInputMessage("sess1", "sub1", "/app/", "dest.foo.bar", null);
@@ -220,7 +215,6 @@ public class SendToMethodReturnValueHandlerTests {
@Test
public void testHeadersToSend() throws Exception {
Message<?> inputMessage = createInputMessage("sess1", "sub1", "/app", "/dest", null);
SimpMessageSendingOperations messagingTemplate = Mockito.mock(SimpMessageSendingOperations.class);
@@ -237,12 +231,11 @@ public class SendToMethodReturnValueHandlerTests {
assertTrue(accessor.isMutable());
assertEquals("sess1", accessor.getSessionId());
assertNull("Subscription id should not be copied", accessor.getSubscriptionId());
assertEquals(this.noAnnotationsReturnType, accessor.getHeader(AbstractMessageConverter.METHOD_PARAMETER_HINT_HEADER));
assertEquals(this.noAnnotationsReturnType, accessor.getHeader(SimpMessagingTemplate.CONVERSION_HINT_HEADER));
}
@Test
public void sendToUser() throws Exception {
given(this.messageChannel.send(any(Message.class))).willReturn(true);
String sessionId = "sess1";
@@ -263,11 +256,8 @@ public class SendToMethodReturnValueHandlerTests {
assertEquals("/user/" + user.getName() + "/dest2", accessor.getDestination());
}
// SPR-12170
@Test
@Test // SPR-12170
public void sendToWithDestinationPlaceholders() throws Exception {
given(this.messageChannel.send(any(Message.class))).willReturn(true);
Map<String, String> vars = new LinkedHashMap<>(1);
@@ -290,7 +280,6 @@ public class SendToMethodReturnValueHandlerTests {
@Test
public void sendToUserSingleSession() throws Exception {
given(this.messageChannel.send(any(Message.class))).willReturn(true);
String sessionId = "sess1";
@@ -305,19 +294,18 @@ public class SendToMethodReturnValueHandlerTests {
assertEquals(MIME_TYPE, accessor.getContentType());
assertEquals("/user/" + user.getName() + "/dest1", accessor.getDestination());
assertNull("Subscription id should not be copied", accessor.getSubscriptionId());
assertEquals(this.sendToUserSingleSessionReturnType, accessor.getHeader(AbstractMessageConverter.METHOD_PARAMETER_HINT_HEADER));
assertEquals(this.sendToUserSingleSessionReturnType, accessor.getHeader(SimpMessagingTemplate.CONVERSION_HINT_HEADER));
accessor = getCapturedAccessor(1);
assertEquals(sessionId, accessor.getSessionId());
assertEquals("/user/" + user.getName() + "/dest2", accessor.getDestination());
assertEquals(MIME_TYPE, accessor.getContentType());
assertNull("Subscription id should not be copied", accessor.getSubscriptionId());
assertEquals(this.sendToUserSingleSessionReturnType, accessor.getHeader(AbstractMessageConverter.METHOD_PARAMETER_HINT_HEADER));
assertEquals(this.sendToUserSingleSessionReturnType, accessor.getHeader(SimpMessagingTemplate.CONVERSION_HINT_HEADER));
}
@Test
public void sendToUserWithUserNameProvider() throws Exception {
given(this.messageChannel.send(any(Message.class))).willReturn(true);
String sessionId = "sess1";
@@ -336,7 +324,6 @@ public class SendToMethodReturnValueHandlerTests {
@Test
public void sendToUserDefaultDestination() throws Exception {
given(this.messageChannel.send(any(Message.class))).willReturn(true);
String sessionId = "sess1";
@@ -354,7 +341,6 @@ public class SendToMethodReturnValueHandlerTests {
@Test
public void sendToUserDefaultDestinationWhenUsingDotPathSeparator() throws Exception {
given(this.messageChannel.send(any(Message.class))).willReturn(true);
TestUser user = new TestUser();
@@ -369,7 +355,6 @@ public class SendToMethodReturnValueHandlerTests {
@Test
public void sendToUserDefaultDestinationSingleSession() throws Exception {
given(this.messageChannel.send(any(Message.class))).willReturn(true);
String sessionId = "sess1";
@@ -384,12 +369,11 @@ public class SendToMethodReturnValueHandlerTests {
assertEquals("/user/" + user.getName() + "/queue/dest", accessor.getDestination());
assertEquals(MIME_TYPE, accessor.getContentType());
assertNull("Subscription id should not be copied", accessor.getSubscriptionId());
assertEquals(this.sendToUserSingleSessionDefaultDestReturnType, accessor.getHeader(AbstractMessageConverter.METHOD_PARAMETER_HINT_HEADER));
assertEquals(this.sendToUserSingleSessionDefaultDestReturnType, accessor.getHeader(SimpMessagingTemplate.CONVERSION_HINT_HEADER));
}
@Test
public void sendToUserSessionWithoutUserName() throws Exception {
given(this.messageChannel.send(any(Message.class))).willReturn(true);
String sessionId = "sess1";
@@ -409,7 +393,6 @@ public class SendToMethodReturnValueHandlerTests {
@Test
public void jsonView() throws Exception {
given(this.messageChannel.send(any(Message.class))).willReturn(true);
String sessionId = "sess1";
@@ -420,7 +403,7 @@ public class SendToMethodReturnValueHandlerTests {
Message<?> message = this.messageCaptor.getValue();
assertNotNull(message);
assertEquals("{\"withView1\":\"with\"}", new String((byte[])message.getPayload(), StandardCharsets.UTF_8));
assertEquals("{\"withView1\":\"with\"}", new String((byte[]) message.getPayload(), StandardCharsets.UTF_8));
}
@@ -515,8 +498,8 @@ public class SendToMethodReturnValueHandlerTests {
}
private interface MyJacksonView1 {};
private interface MyJacksonView2 {};
private interface MyJacksonView1 {}
private interface MyJacksonView2 {}
@SuppressWarnings("unused")
private static class JacksonViewBean {

View File

@@ -34,7 +34,6 @@ import org.springframework.core.MethodParameter;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.converter.AbstractMessageConverter;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;
import org.springframework.messaging.converter.StringMessageConverter;
import org.springframework.messaging.core.MessageSendingOperations;
@@ -82,7 +81,6 @@ public class SubscriptionMethodReturnValueHandlerTests {
@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
SimpMessagingTemplate messagingTemplate = new SimpMessagingTemplate(this.messageChannel);
@@ -116,7 +114,6 @@ public class SubscriptionMethodReturnValueHandlerTests {
@Test
public void testMessageSentToChannel() throws Exception {
given(this.messageChannel.send(any(Message.class))).willReturn(true);
String sessionId = "sess1";
@@ -138,13 +135,12 @@ public class SubscriptionMethodReturnValueHandlerTests {
assertEquals(subscriptionId, headerAccessor.getSubscriptionId());
assertEquals(destination, headerAccessor.getDestination());
assertEquals(MIME_TYPE, headerAccessor.getContentType());
assertEquals(this.subscribeEventReturnType, headerAccessor.getHeader(AbstractMessageConverter.METHOD_PARAMETER_HINT_HEADER));
assertEquals(this.subscribeEventReturnType, headerAccessor.getHeader(SimpMessagingTemplate.CONVERSION_HINT_HEADER));
}
@Test
@SuppressWarnings({ "unchecked", "rawtypes" })
public void testHeadersPassedToMessagingTemplate() throws Exception {
String sessionId = "sess1";
String subscriptionId = "subs1";
String destination = "/dest";
@@ -165,12 +161,11 @@ public class SubscriptionMethodReturnValueHandlerTests {
assertTrue(headerAccessor.isMutable());
assertEquals(sessionId, headerAccessor.getSessionId());
assertEquals(subscriptionId, headerAccessor.getSubscriptionId());
assertEquals(this.subscribeEventReturnType, headerAccessor.getHeader(AbstractMessageConverter.METHOD_PARAMETER_HINT_HEADER));
assertEquals(this.subscribeEventReturnType, headerAccessor.getHeader(SimpMessagingTemplate.CONVERSION_HINT_HEADER));
}
@Test
public void testJsonView() throws Exception {
given(this.messageChannel.send(any(Message.class))).willReturn(true);
String sessionId = "sess1";
@@ -184,7 +179,7 @@ public class SubscriptionMethodReturnValueHandlerTests {
Message<?> message = this.messageCaptor.getValue();
assertNotNull(message);
assertEquals("{\"withView1\":\"with\"}", new String((byte[])message.getPayload(), StandardCharsets.UTF_8));
assertEquals("{\"withView1\":\"with\"}", new String((byte[]) message.getPayload(), StandardCharsets.UTF_8));
}