From b1d6ae77e1be510580be14e7324925f6e5d12efb Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Thu, 30 Jul 2015 00:08:36 +0200 Subject: [PATCH] Polishing --- .../MessageMethodArgumentResolver.java | 21 +++++++--------- .../SendToMethodReturnValueHandler.java | 25 +++++++++++-------- .../SubscriptionMethodReturnValueHandler.java | 10 +++++--- .../MessageMethodArgumentResolverTests.java | 3 ++- .../StompWebSocketIntegrationTests.java | 25 ++++++++----------- 5 files changed, 41 insertions(+), 43 deletions(-) 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 58b9729600..d13658cc9e 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -22,10 +22,11 @@ import org.springframework.core.MethodParameter; import org.springframework.core.ResolvableType; import org.springframework.messaging.Message; import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver; +import org.springframework.util.ClassUtils; /** - * A {@link HandlerMethodArgumentResolver} for {@link Message} parameters. Validates - * that the generic type of the payload matches with the message value. + * A {@link HandlerMethodArgumentResolver} for {@link Message} parameters. + * Validates that the generic type of the payload matches with the message value. * * @author Rossen Stoyanchev * @author Stephane Nicoll @@ -33,7 +34,6 @@ import org.springframework.messaging.handler.invocation.HandlerMethodArgumentRes */ public class MessageMethodArgumentResolver implements HandlerMethodArgumentResolver { - @Override public boolean supportsParameter(MethodParameter parameter) { return Message.class.isAssignableFrom(parameter.getParameterType()); @@ -41,22 +41,19 @@ public class MessageMethodArgumentResolver implements HandlerMethodArgumentResol @Override public Object resolveArgument(MethodParameter parameter, Message message) throws Exception { - Class paramType = parameter.getParameterType(); - if (!paramType.isAssignableFrom(message.getClass())) { throw new MethodArgumentTypeMismatchException(message, parameter, - "The actual message type [" + message.getClass().getName() + "] " + - "does not match the expected type [" + paramType.getName() + "]"); + "The actual message type [" + ClassUtils.getQualifiedName(message.getClass()) + "] " + + "does not match the expected type [" + ClassUtils.getQualifiedName(paramType) + "]"); } Class expectedPayloadType = getPayloadType(parameter); Object payload = message.getPayload(); - - if (expectedPayloadType != null && !expectedPayloadType.isInstance(payload)) { + if (payload != null && expectedPayloadType != null && !expectedPayloadType.isInstance(payload)) { throw new MethodArgumentTypeMismatchException(message, parameter, - "The expected Message payload type [" + expectedPayloadType.getName() + - "] does not match the actual payload type [" + payload.getClass().getName() + "]"); + "The expected Message payload type [" + ClassUtils.getQualifiedName(expectedPayloadType) + + "] does not match the actual payload type [" + ClassUtils.getQualifiedName(payload.getClass()) + "]"); } return message; diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandler.java index 4a340304e6..3d283f4158 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SendToMethodReturnValueHandler.java @@ -40,16 +40,16 @@ import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.util.PropertyPlaceholderHelper; import org.springframework.util.PropertyPlaceholderHelper.PlaceholderResolver; +import org.springframework.util.StringUtils; /** * A {@link HandlerMethodReturnValueHandler} for sending to destinations specified in a * {@link SendTo} or {@link SendToUser} method-level annotations. * *

The value returned from the method is converted, and turned to a {@link Message} and - * sent through the provided {@link MessageChannel}. The - * message is then enriched with the sessionId of the input message as well as the - * destination from the annotation(s). If multiple destinations are specified, a copy of - * the message is sent to each destination. + * sent through the provided {@link MessageChannel}. The message is then enriched with the + * session id of the input message as well as the destination from the annotation(s). + * If multiple destinations are specified, a copy of the message is sent to each destination. * * @author Rossen Stoyanchev * @author Sebastien Deleuze @@ -116,7 +116,6 @@ public class SendToMethodReturnValueHandler implements HandlerMethodReturnValueH /** * Configure a {@link MessageHeaderInitializer} to apply to the headers of all * messages sent to the client outbound channel. - * *

By default this property is not set. */ public void setHeaderInitializer(MessageHeaderInitializer headerInitializer) { @@ -133,8 +132,8 @@ public class SendToMethodReturnValueHandler implements HandlerMethodReturnValueH @Override public boolean supportsReturnType(MethodParameter returnType) { - if ((returnType.getMethodAnnotation(SendTo.class) != null) || - (returnType.getMethodAnnotation(SendToUser.class) != null)) { + if (returnType.getMethodAnnotation(SendTo.class) != null || + returnType.getMethodAnnotation(SendToUser.class) != null) { return true; } return (!this.annotationRequired); @@ -164,10 +163,12 @@ public class SendToMethodReturnValueHandler implements HandlerMethodReturnValueH for (String destination : destinations) { destination = this.placeholderHelper.replacePlaceholders(destination, varResolver); if (broadcast) { - this.messagingTemplate.convertAndSendToUser(user, destination, returnValue, createHeaders(null, returnType)); + this.messagingTemplate.convertAndSendToUser( + user, destination, returnValue, createHeaders(null, returnType)); } else { - this.messagingTemplate.convertAndSendToUser(user, destination, returnValue, createHeaders(sessionId, returnType)); + this.messagingTemplate.convertAndSendToUser( + user, destination, returnValue, createHeaders(sessionId, returnType)); } } } @@ -206,7 +207,9 @@ public class SendToMethodReturnValueHandler implements HandlerMethodReturnValueH } String name = DestinationPatternsMessageCondition.LOOKUP_DESTINATION_HEADER; String destination = (String) message.getHeaders().get(name); - Assert.hasText(destination, "No lookup destination header in " + message); + if (!StringUtils.hasText(destination)) { + throw new IllegalStateException("No lookup destination header in " + message); + } return (destination.startsWith("/") ? new String[] {defaultPrefix + destination} : new String[] {defaultPrefix + "/" + destination}); @@ -231,11 +234,11 @@ public class SendToMethodReturnValueHandler implements HandlerMethodReturnValueH return "SendToMethodReturnValueHandler [annotationRequired=" + annotationRequired + "]"; } + private static class DestinationVariablePlaceholderResolver implements PlaceholderResolver { private final Map vars; - public DestinationVariablePlaceholderResolver(Map vars) { this.vars = vars; } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SubscriptionMethodReturnValueHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SubscriptionMethodReturnValueHandler.java index b0fa04bce0..085446fab9 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SubscriptionMethodReturnValueHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SubscriptionMethodReturnValueHandler.java @@ -104,14 +104,16 @@ public class SubscriptionMethodReturnValueHandler implements HandlerMethodReturn String sessionId = SimpMessageHeaderAccessor.getSessionId(headers); String subscriptionId = SimpMessageHeaderAccessor.getSubscriptionId(headers); - Assert.state(subscriptionId != null, - "No subscriptionId in message=" + message + ", method=" + returnType.getMethod()); + if (subscriptionId == null) { + throw new IllegalStateException( + "No subscriptionId in " + message + " returned by: " + returnType.getMethod()); + } if (logger.isDebugEnabled()) { logger.debug("Reply to @SubscribeMapping: " + returnValue); } - - this.messagingTemplate.convertAndSend(destination, returnValue, createHeaders(sessionId, subscriptionId, returnType)); + this.messagingTemplate.convertAndSend( + destination, returnValue, createHeaders(sessionId, subscriptionId, returnType)); } private MessageHeaders createHeaders(String sessionId, String subscriptionId, MethodParameter returnType) { 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 7c6523e7a2..f4b7e2baf4 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-2014 the original author or authors. + * Copyright 2002-2015 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. @@ -145,6 +145,7 @@ public class MessageMethodArgumentResolverTests { assertSame(message, this.resolver.resolveArgument(parameter, message)); } + @SuppressWarnings("unused") private void handleMessage( Message wildcardPayload, diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/messaging/StompWebSocketIntegrationTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/messaging/StompWebSocketIntegrationTests.java index 8637f45971..cd16da96b5 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/messaging/StompWebSocketIntegrationTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/messaging/StompWebSocketIntegrationTests.java @@ -83,13 +83,12 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration @Override protected Class[] getAnnotatedConfigClasses() { - return new Class[] { TestMessageBrokerConfiguration.class, TestMessageBrokerConfigurer.class }; + return new Class[] {TestMessageBrokerConfiguration.class, TestMessageBrokerConfigurer.class}; } @Test public void sendMessageToController() throws Exception { - TextMessage message = create(StompCommand.SEND).headers("destination:/app/simple").build(); WebSocketSession session = doHandshake(new TestClientWebSocketHandler(0, message), "/ws").get(); @@ -104,10 +103,8 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration @Test public void sendMessageToControllerAndReceiveReplyViaTopic() throws Exception { - TextMessage message1 = create(StompCommand.SUBSCRIBE) .headers("id:subs1", "destination:/topic/increment").build(); - TextMessage message2 = create(StompCommand.SEND) .headers("destination:/app/increment").body("5").build(); @@ -126,7 +123,6 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration @Test public void sendMessageToBrokerAndReceiveReplyViaTopic() throws Exception { - TextMessage m1 = create(StompCommand.SUBSCRIBE).headers("id:subs1", "destination:/topic/foo").build(); TextMessage m2 = create(StompCommand.SEND).headers("destination:/topic/foo").body("5").build(); @@ -148,7 +144,6 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration @Test public void sendSubscribeToControllerAndReceiveReply() throws Exception { - String destHeader = "destination:/app/number"; TextMessage message = create(StompCommand.SUBSCRIBE).headers("id:subs1", destHeader).build(); @@ -168,7 +163,6 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration @Test public void handleExceptionAndSendToUser() throws Exception { - String destHeader = "destination:/user/queue/error"; TextMessage m1 = create(StompCommand.SUBSCRIBE).headers("id:subs1", destHeader).build(); TextMessage m2 = create(StompCommand.SEND).headers("destination:/app/exception").build(); @@ -178,7 +172,6 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration try { assertTrue(clientHandler.latch.await(2, TimeUnit.SECONDS)); - String payload = clientHandler.actual.get(0).getPayload(); assertTrue(payload.startsWith("MESSAGE\n")); assertTrue(payload.contains("destination:/user/queue/error\n")); @@ -191,10 +184,8 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration @Test public void webSocketScope() throws Exception { - TextMessage message1 = create(StompCommand.SUBSCRIBE) .headers("id:subs1", "destination:/topic/scopedBeanValue").build(); - TextMessage message2 = create(StompCommand.SEND) .headers("destination:/app/scopedBeanValue").build(); @@ -203,7 +194,6 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration try { assertTrue(clientHandler.latch.await(2, TimeUnit.SECONDS)); - String payload = clientHandler.actual.get(0).getPayload(); assertTrue(payload.startsWith("MESSAGE\n")); assertTrue(payload.contains("destination:/topic/scopedBeanValue\n")); @@ -221,6 +211,7 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration private @interface IntegrationTestController { } + @IntegrationTestController static class SimpleController { @@ -243,6 +234,7 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration } } + @IntegrationTestController static class IncrementController { @@ -257,6 +249,7 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration } } + @IntegrationTestController static class ScopedBeanController { @@ -279,6 +272,7 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration String getValue(); } + static class ScopedBeanImpl implements ScopedBean { private final String value; @@ -304,7 +298,6 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration private final CountDownLatch latch; - public TestClientWebSocketHandler(int expectedNumberOfMessages, TextMessage... messagesToSend) { this.messagesToSend = messagesToSend; this.expected = expectedNumberOfMessages; @@ -325,6 +318,7 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration } } + @Configuration @ComponentScan( basePackageClasses=StompWebSocketIntegrationTests.class, @@ -333,7 +327,7 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration static class TestMessageBrokerConfigurer extends AbstractWebSocketMessageBrokerConfigurer { @Autowired - private HandshakeHandler handshakeHandler; // can't rely on classpath for server detection + private HandshakeHandler handshakeHandler; // can't rely on classpath for server detection @Override public void registerStompEndpoints(StompEndpointRegistry registry) { @@ -353,19 +347,20 @@ public class StompWebSocketIntegrationTests extends AbstractWebSocketIntegration } } + @Configuration static class TestMessageBrokerConfiguration extends DelegatingWebSocketMessageBrokerConfiguration { @Override @Bean public AbstractSubscribableChannel clientInboundChannel() { - return new ExecutorSubscribableChannel(); // synchronous + return new ExecutorSubscribableChannel(); // synchronous } @Override @Bean public AbstractSubscribableChannel clientOutboundChannel() { - return new ExecutorSubscribableChannel(); // synchronous + return new ExecutorSubscribableChannel(); // synchronous } }