From 55494362efa7d7702aa5bfecc0766a448d019707 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 (cherry picked from commit e8417ea) --- .../SimpAnnotationMethodMessageHandler.java | 30 ++++++++++--------- .../support/MessageHeaderAccessor.java | 12 ++++---- 2 files changed, 23 insertions(+), 19 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 25a0878083..c50de79b9d 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 @@ -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. @@ -64,7 +64,6 @@ import org.springframework.messaging.support.MessageHeaderInitializer; import org.springframework.stereotype.Controller; import org.springframework.util.AntPathMatcher; import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; import org.springframework.util.PathMatcher; import org.springframework.validation.Validator; @@ -289,9 +288,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(); @@ -315,11 +313,13 @@ public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHan List handlers = new ArrayList(); // 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); @@ -429,13 +429,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);