From e8417ea6e152a1864a86deee82776804e300873f Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 24 Nov 2015 17:37:12 +0100 Subject: [PATCH] SimpAnnotationMethodMessageHandler skips template variable check in case of no pattern Issue: SPR-13704 --- .../SimpAnnotationMethodMessageHandler.java | 32 ++++++++++--------- .../support/MessageHeaderAccessor.java | 12 ++++--- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SimpAnnotationMethodMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SimpAnnotationMethodMessageHandler.java index 75d0dc0ec7..aff2a293e4 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SimpAnnotationMethodMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/annotation/support/SimpAnnotationMethodMessageHandler.java @@ -86,8 +86,8 @@ import org.springframework.validation.Validator; public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHandler implements EmbeddedValueResolverAware, SmartLifecycle { - private static final boolean completableFuturePresent = ClassUtils.isPresent("java.util.concurrent.CompletableFuture", - SimpAnnotationMethodMessageHandler.class.getClassLoader()); + private static final boolean completableFuturePresent = ClassUtils.isPresent( + "java.util.concurrent.CompletableFuture", SimpAnnotationMethodMessageHandler.class.getClassLoader()); private final SubscribableChannel clientInboundChannel; @@ -304,9 +304,8 @@ public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHan protected List initArgumentResolvers() { - ConfigurableBeanFactory beanFactory = - (ClassUtils.isAssignableValue(ConfigurableApplicationContext.class, getApplicationContext())) ? - ((ConfigurableApplicationContext) getApplicationContext()).getBeanFactory() : null; + ConfigurableBeanFactory beanFactory = (getApplicationContext() instanceof ConfigurableApplicationContext ? + ((ConfigurableApplicationContext) getApplicationContext()).getBeanFactory() : null); List resolvers = new ArrayList(); @@ -327,7 +326,6 @@ public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHan @Override protected List initReturnValueHandlers() { - List handlers = new ArrayList(); // Single-purpose return value types @@ -337,11 +335,13 @@ public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHan } // Annotation-based return value types - SendToMethodReturnValueHandler sth = new SendToMethodReturnValueHandler(this.brokerTemplate, true); + SendToMethodReturnValueHandler sth = + new SendToMethodReturnValueHandler(this.brokerTemplate, true); sth.setHeaderInitializer(this.headerInitializer); handlers.add(sth); - SubscriptionMethodReturnValueHandler sh = new SubscriptionMethodReturnValueHandler(this.clientMessagingTemplate); + SubscriptionMethodReturnValueHandler sh = + new SubscriptionMethodReturnValueHandler(this.clientMessagingTemplate); sh.setHeaderInitializer(this.headerInitializer); handlers.add(sh); @@ -468,13 +468,15 @@ public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHan protected void handleMatch(SimpMessageMappingInfo mapping, HandlerMethod handlerMethod, String lookupDestination, Message message) { - String matchedPattern = mapping.getDestinationConditions().getPatterns().iterator().next(); - Map vars = getPathMatcher().extractUriTemplateVariables(matchedPattern, lookupDestination); - - if (!CollectionUtils.isEmpty(vars)) { - MessageHeaderAccessor accessor = MessageHeaderAccessor.getAccessor(message, MessageHeaderAccessor.class); - Assert.state(accessor != null && accessor.isMutable()); - accessor.setHeader(DestinationVariableMethodArgumentResolver.DESTINATION_TEMPLATE_VARIABLES_HEADER, vars); + Set patterns = mapping.getDestinationConditions().getPatterns(); + if (!CollectionUtils.isEmpty(patterns)) { + String pattern = patterns.iterator().next(); + Map vars = getPathMatcher().extractUriTemplateVariables(pattern, lookupDestination); + if (!CollectionUtils.isEmpty(vars)) { + MessageHeaderAccessor mha = MessageHeaderAccessor.getAccessor(message, MessageHeaderAccessor.class); + Assert.state(mha != null && mha.isMutable()); + mha.setHeader(DestinationVariableMethodArgumentResolver.DESTINATION_TEMPLATE_VARIABLES_HEADER, vars); + } } try { diff --git a/spring-messaging/src/main/java/org/springframework/messaging/support/MessageHeaderAccessor.java b/spring-messaging/src/main/java/org/springframework/messaging/support/MessageHeaderAccessor.java index 1036de0c4b..8a84f6f872 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/support/MessageHeaderAccessor.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/support/MessageHeaderAccessor.java @@ -319,7 +319,8 @@ public class MessageHeaderAccessor { protected void verifyType(String headerName, Object headerValue) { if (headerName != null && headerValue != null) { - if (MessageHeaders.ERROR_CHANNEL.equals(headerName) || MessageHeaders.REPLY_CHANNEL.endsWith(headerName)) { + if (MessageHeaders.ERROR_CHANNEL.equals(headerName) || + MessageHeaders.REPLY_CHANNEL.endsWith(headerName)) { if (!(headerValue instanceof MessageChannel || headerValue instanceof String)) { throw new IllegalArgumentException( "'" + headerName + "' header value must be a MessageChannel or String"); @@ -572,11 +573,13 @@ public class MessageHeaderAccessor { * A variation of {@link #getAccessor(org.springframework.messaging.Message, Class)} * with a {@code MessageHeaders} instance instead of a {@code Message}. *

This is for cases when a full message may not have been created yet. - * @return an accessor instance of the specified typem or {@code null} if none + * @return an accessor instance of the specified type, or {@code null} if none * @since 4.1 */ @SuppressWarnings("unchecked") - public static T getAccessor(MessageHeaders messageHeaders, Class requiredType) { + public static T getAccessor( + MessageHeaders messageHeaders, Class requiredType) { + if (messageHeaders instanceof MutableMessageHeaders) { MutableMessageHeaders mutableHeaders = (MutableMessageHeaders) messageHeaders; MessageHeaderAccessor headerAccessor = mutableHeaders.getMessageHeaderAccessor(); @@ -593,7 +596,7 @@ public class MessageHeaderAccessor { * wrapping the message with a {@code MessageHeaderAccessor} instance. *

This is for cases where a header needs to be updated in generic code * while preserving the accessor type for downstream processing. - * @return an accessor of the required type, never {@code null}. + * @return an accessor of the required type (never {@code null}) * @since 4.1 */ public static MessageHeaderAccessor getMutableAccessor(Message message) { @@ -646,7 +649,6 @@ public class MessageHeaderAccessor { if (getId() == null) { IdGenerator idGenerator = (MessageHeaderAccessor.this.idGenerator != null ? MessageHeaderAccessor.this.idGenerator : MessageHeaders.getIdGenerator()); - UUID id = idGenerator.generateId(); if (id != null && id != MessageHeaders.ID_VALUE_NONE) { getRawHeaders().put(ID, id); -- GitLab