diff --git a/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java b/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java index 580c97878f0..dfbab72e000 100644 --- a/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java +++ b/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java @@ -68,6 +68,23 @@ public class AntPathMatcher implements PathMatcher { final Map stringMatcherCache = new ConcurrentHashMap(256); + /** + * Create a new AntPathMatcher with the default Ant path separator "/". + */ + public AntPathMatcher() { + + } + + /** + * Create a new AntPathMatcher. + * @param pathSeparator the path separator to use + * @since 4.1 + */ + public AntPathMatcher(String pathSeparator) { + if(pathSeparator != null) { + this.pathSeparator = pathSeparator; + } + } /** * Set the path separator to use for pattern parsing. @@ -430,20 +447,20 @@ public class AntPathMatcher implements PathMatcher { // /hotels/* + /booking -> /hotels/booking // /hotels/* + booking -> /hotels/booking - if (pattern1.endsWith("/*")) { - return slashConcat(pattern1.substring(0, pattern1.length() - 2), pattern2); + if (pattern1.endsWith(this.pathSeparator + "*")) { + return separatorConcat(pattern1.substring(0, pattern1.length() - 2), pattern2); } // /hotels/** + /booking -> /hotels/**/booking // /hotels/** + booking -> /hotels/**/booking - if (pattern1.endsWith("/**")) { - return slashConcat(pattern1, pattern2); + if (pattern1.endsWith(this.pathSeparator + "**")) { + return separatorConcat(pattern1, pattern2); } int starDotPos1 = pattern1.indexOf("*."); - if (pattern1ContainsUriVar || starDotPos1 == -1) { + if (pattern1ContainsUriVar || starDotPos1 == -1 || this.pathSeparator.equals(".")) { // simply concatenate the two patterns - return slashConcat(pattern1, pattern2); + return separatorConcat(pattern1, pattern2); } String extension1 = pattern1.substring(starDotPos1 + 1); int dotPos2 = pattern2.indexOf('.'); @@ -453,11 +470,11 @@ public class AntPathMatcher implements PathMatcher { return fileName2 + extension; } - private String slashConcat(String path1, String path2) { - if (path1.endsWith("/") || path2.startsWith("/")) { + private String separatorConcat(String path1, String path2) { + if (path1.endsWith(this.pathSeparator) || path2.startsWith(this.pathSeparator)) { return path1 + path2; } - return path1 + "/" + path2; + return path1 + this.pathSeparator + path2; } /** diff --git a/spring-core/src/test/java/org/springframework/util/AntPathMatcherTests.java b/spring-core/src/test/java/org/springframework/util/AntPathMatcherTests.java index 3ef3acd54cf..3f678ec3fd4 100644 --- a/spring-core/src/test/java/org/springframework/util/AntPathMatcherTests.java +++ b/spring-core/src/test/java/org/springframework/util/AntPathMatcherTests.java @@ -606,4 +606,10 @@ public class AntPathMatcherTests { assertTrue(pathMatcher.stringMatcherCache.isEmpty()); } + @Test + public void noExtensionHandlingWithDotSeparator() { + pathMatcher.setPathSeparator("."); + assertEquals("/*.html.hotel.*", pathMatcher.combine("/*.html", "hotel.*")); + } + } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/DestinationPatternsMessageCondition.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/DestinationPatternsMessageCondition.java index 12ff720e41f..a3e3fe843d7 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/DestinationPatternsMessageCondition.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/DestinationPatternsMessageCondition.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -55,21 +55,35 @@ public final class DestinationPatternsMessageCondition * @param patterns 0 or more URL patterns; if 0 the condition will match to every request. */ public DestinationPatternsMessageCondition(String... patterns) { - this(patterns, null); + this(patterns, null, true); } /** - * Additional constructor with flags for using suffix pattern (.*) and - * trailing slash matches. + * Additional constructor with a customized path matcher. * @param patterns the URL patterns to use; if 0, the condition will match to every request. - * @param pathMatcher for path matching with patterns + * @param pathMatcher the customized path matcher to use with patterns */ - public DestinationPatternsMessageCondition(String[] patterns,PathMatcher pathMatcher) { - this(asList(patterns), pathMatcher); + public DestinationPatternsMessageCondition(String[] patterns, PathMatcher pathMatcher) { + this(asList(patterns), pathMatcher, true); } - private DestinationPatternsMessageCondition(Collection patterns, PathMatcher pathMatcher) { - this.patterns = Collections.unmodifiableSet(prependLeadingSlash(patterns)); + /** + * Additional constructor with a customized path matcher and a flag specifying if + * the destination patterns should be prepended with "/". + * @param patterns the URL patterns to use; if 0, the condition will match to every request. + * @param pathMatcher the customized path matcher to use with patterns + * @param prependLeadingSlash to specify whether each pattern that is not empty and does not + * start with "/" will be prepended with "/" or not + * @since 4.1 + */ + public DestinationPatternsMessageCondition(String[] patterns, PathMatcher pathMatcher, + boolean prependLeadingSlash) { + this(asList(patterns), pathMatcher, prependLeadingSlash); + } + + private DestinationPatternsMessageCondition(Collection patterns, + PathMatcher pathMatcher, boolean prependLeadingSlash) { + this.patterns = Collections.unmodifiableSet(initializePatterns(patterns, prependLeadingSlash)); this.pathMatcher = (pathMatcher != null) ? pathMatcher : new AntPathMatcher(); } @@ -77,13 +91,14 @@ public final class DestinationPatternsMessageCondition return patterns != null ? Arrays.asList(patterns) : Collections.emptyList(); } - private static Set prependLeadingSlash(Collection patterns) { + private static Set initializePatterns(Collection patterns, + boolean prependLeadingSlash) { if (patterns == null) { return Collections.emptySet(); } Set result = new LinkedHashSet(patterns.size()); for (String pattern : patterns) { - if (StringUtils.hasLength(pattern) && !pattern.startsWith("/")) { + if (StringUtils.hasLength(pattern) && !pattern.startsWith("/") && prependLeadingSlash) { pattern = "/" + pattern; } result.add(pattern); @@ -134,7 +149,7 @@ public final class DestinationPatternsMessageCondition else { result.add(""); } - return new DestinationPatternsMessageCondition(result, this.pathMatcher); + return new DestinationPatternsMessageCondition(result, this.pathMatcher, false); } /** @@ -169,7 +184,7 @@ public final class DestinationPatternsMessageCondition } Collections.sort(matches, this.pathMatcher.getPatternComparator(destination)); - return new DestinationPatternsMessageCondition(matches, this.pathMatcher); + return new DestinationPatternsMessageCondition(matches, this.pathMatcher, false); } /** 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 0e82b56134b..f6a4600cfc1 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 @@ -52,7 +52,6 @@ import org.springframework.messaging.handler.invocation.AbstractExceptionHandler import org.springframework.messaging.handler.invocation.AbstractMethodMessageHandler; import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver; import org.springframework.messaging.handler.invocation.HandlerMethodReturnValueHandler; -import org.springframework.messaging.simp.SimpAttributes; import org.springframework.messaging.simp.SimpAttributesContextHolder; import org.springframework.messaging.simp.SimpMessageHeaderAccessor; import org.springframework.messaging.simp.SimpMessageMappingInfo; @@ -94,7 +93,7 @@ public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHan private ConversionService conversionService = new DefaultFormattingConversionService(); - private PathMatcher pathMatcher = new AntPathMatcher(); + private PathMatcher pathMatcher; private Validator validator; @@ -113,7 +112,22 @@ public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHan * @param brokerTemplate a messaging template to send application messages to the broker */ public SimpAnnotationMethodMessageHandler(SubscribableChannel clientInboundChannel, - MessageChannel clientOutboundChannel, SimpMessageSendingOperations brokerTemplate) { + MessageChannel clientOutboundChannel, SimpMessageSendingOperations brokerTemplate) { + this(clientInboundChannel, clientOutboundChannel, brokerTemplate, null); + } + + /** + * Create an instance of SimpAnnotationMethodMessageHandler with the given + * message channels and broker messaging template. + * @param clientInboundChannel the channel for receiving messages from clients (e.g. WebSocket clients) + * @param clientOutboundChannel the channel for messages to clients (e.g. WebSocket clients) + * @param brokerTemplate a messaging template to send application messages to the broker + * @param pathSeparator the path separator to use with the destination patterns + * @since 4.1 + */ + public SimpAnnotationMethodMessageHandler(SubscribableChannel clientInboundChannel, + MessageChannel clientOutboundChannel, SimpMessageSendingOperations brokerTemplate, + String pathSeparator) { Assert.notNull(clientInboundChannel, "clientInboundChannel must not be null"); Assert.notNull(clientOutboundChannel, "clientOutboundChannel must not be null"); @@ -122,6 +136,7 @@ public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHan this.clientInboundChannel = clientInboundChannel; this.clientMessagingTemplate = new SimpMessagingTemplate(clientOutboundChannel); this.brokerTemplate = brokerTemplate; + this.pathMatcher = new AntPathMatcher(pathSeparator); Collection converters = new ArrayList(); converters.add(new StringMessageConverter()); @@ -318,31 +333,31 @@ public class SimpAnnotationMethodMessageHandler extends AbstractMethodMessageHan MessageMapping typeAnnotation = AnnotationUtils.findAnnotation(handlerType, MessageMapping.class); MessageMapping messageAnnot = AnnotationUtils.findAnnotation(method, MessageMapping.class); if (messageAnnot != null) { - SimpMessageMappingInfo result = createMessageMappingCondition(messageAnnot); + SimpMessageMappingInfo result = createMessageMappingCondition(messageAnnot, typeAnnotation == null); if (typeAnnotation != null) { - result = createMessageMappingCondition(typeAnnotation).combine(result); + result = createMessageMappingCondition(typeAnnotation, false).combine(result); } return result; } SubscribeMapping subsribeAnnotation = AnnotationUtils.findAnnotation(method, SubscribeMapping.class); if (subsribeAnnotation != null) { - SimpMessageMappingInfo result = createSubscribeCondition(subsribeAnnotation); + SimpMessageMappingInfo result = createSubscribeCondition(subsribeAnnotation, typeAnnotation == null); if (typeAnnotation != null) { - result = createMessageMappingCondition(typeAnnotation).combine(result); + result = createMessageMappingCondition(typeAnnotation, false).combine(result); } return result; } return null; } - private SimpMessageMappingInfo createMessageMappingCondition(MessageMapping annotation) { + private SimpMessageMappingInfo createMessageMappingCondition(MessageMapping annotation, boolean prependLeadingSlash) { return new SimpMessageMappingInfo(SimpMessageTypeMessageCondition.MESSAGE, - new DestinationPatternsMessageCondition(annotation.value())); + new DestinationPatternsMessageCondition(annotation.value(), this.pathMatcher, prependLeadingSlash)); } - private SimpMessageMappingInfo createSubscribeCondition(SubscribeMapping annotation) { + private SimpMessageMappingInfo createSubscribeCondition(SubscribeMapping annotation, boolean prependLeadingSlash) { return new SimpMessageMappingInfo(SimpMessageTypeMessageCondition.SUBSCRIBE, - new DestinationPatternsMessageCondition(annotation.value())); + new DestinationPatternsMessageCondition(annotation.value(), this.pathMatcher, prependLeadingSlash)); } @Override diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/SimpleBrokerMessageHandler.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/SimpleBrokerMessageHandler.java index 01cfca499f8..92b4bb0802e 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/SimpleBrokerMessageHandler.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/broker/SimpleBrokerMessageHandler.java @@ -29,6 +29,7 @@ import org.springframework.messaging.support.MessageHeaderAccessor; import org.springframework.messaging.support.MessageHeaderInitializer; import org.springframework.util.Assert; import org.springframework.util.MultiValueMap; +import org.springframework.util.PathMatcher; /** * A "simple" message broker that recognizes the message types defined in @@ -48,7 +49,7 @@ public class SimpleBrokerMessageHandler extends AbstractBrokerMessageHandler { private final SubscribableChannel brokerChannel; - private SubscriptionRegistry subscriptionRegistry = new DefaultSubscriptionRegistry(); + private SubscriptionRegistry subscriptionRegistry; private MessageHeaderInitializer headerInitializer; @@ -63,6 +64,20 @@ public class SimpleBrokerMessageHandler extends AbstractBrokerMessageHandler { */ public SimpleBrokerMessageHandler(SubscribableChannel clientInboundChannel, MessageChannel clientOutboundChannel, SubscribableChannel brokerChannel, Collection destinationPrefixes) { + this(clientInboundChannel, clientOutboundChannel, brokerChannel, destinationPrefixes, null); + } + + /** + * Additional constructor with a customized path matcher. + * + * @param clientInboundChannel the channel for receiving messages from clients (e.g. WebSocket clients) + * @param clientOutboundChannel the channel for sending messages to clients (e.g. WebSocket clients) + * @param brokerChannel the channel for the application to send messages to the broker + * @param pathMatcher the path matcher to use + * @since 4.1 + */ + public SimpleBrokerMessageHandler(SubscribableChannel clientInboundChannel, MessageChannel clientOutboundChannel, + SubscribableChannel brokerChannel, Collection destinationPrefixes, PathMatcher pathMatcher) { super(destinationPrefixes); Assert.notNull(clientInboundChannel, "'clientInboundChannel' must not be null"); @@ -71,6 +86,11 @@ public class SimpleBrokerMessageHandler extends AbstractBrokerMessageHandler { this.clientInboundChannel = clientInboundChannel; this.clientOutboundChannel = clientOutboundChannel; this.brokerChannel = brokerChannel; + DefaultSubscriptionRegistry subscriptionRegistry = new DefaultSubscriptionRegistry(); + if(pathMatcher != null) { + subscriptionRegistry.setPathMatcher(pathMatcher); + } + this.subscriptionRegistry = subscriptionRegistry; } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractBrokerRegistration.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractBrokerRegistration.java index 8a085da3eab..843b1681dff 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractBrokerRegistration.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractBrokerRegistration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -23,7 +23,6 @@ import java.util.List; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.SubscribableChannel; -import org.springframework.messaging.simp.broker.AbstractBrokerMessageHandler; import org.springframework.util.Assert; /** @@ -67,6 +66,4 @@ public abstract class AbstractBrokerRegistration { return this.destinationPrefixes; } - protected abstract AbstractBrokerMessageHandler getMessageHandler(SubscribableChannel brokerChannel); - } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractMessageBrokerConfiguration.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractMessageBrokerConfiguration.java index 93da70c9981..9661ca4e0f1 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractMessageBrokerConfiguration.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/config/AbstractMessageBrokerConfiguration.java @@ -39,6 +39,7 @@ import org.springframework.messaging.simp.user.UserSessionRegistry; import org.springframework.messaging.support.AbstractSubscribableChannel; import org.springframework.messaging.support.ExecutorSubscribableChannel; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.util.AntPathMatcher; import org.springframework.util.ClassUtils; import org.springframework.util.MimeTypeUtils; import org.springframework.validation.Errors; @@ -206,12 +207,16 @@ public abstract class AbstractMessageBrokerConfiguration implements ApplicationC @Bean public SimpAnnotationMethodMessageHandler simpAnnotationMethodMessageHandler() { + String defaultSeparator = this.getBrokerRegistry().getDefaultSeparator(); SimpAnnotationMethodMessageHandler handler = new SimpAnnotationMethodMessageHandler( - clientInboundChannel(), clientOutboundChannel(), brokerMessagingTemplate()); + clientInboundChannel(), clientOutboundChannel(), brokerMessagingTemplate(), defaultSeparator); handler.setDestinationPrefixes(getBrokerRegistry().getApplicationDestinationPrefixes()); handler.setMessageConverter(brokerMessageConverter()); handler.setValidator(simpValidator()); + + AntPathMatcher pathMatcher = new AntPathMatcher(defaultSeparator); + handler.setPathMatcher(pathMatcher); return handler; } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/config/MessageBrokerRegistry.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/config/MessageBrokerRegistry.java index 11400f9eefe..c1d43d108a3 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/config/MessageBrokerRegistry.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/config/MessageBrokerRegistry.java @@ -23,12 +23,14 @@ import org.springframework.messaging.MessageChannel; import org.springframework.messaging.SubscribableChannel; import org.springframework.messaging.simp.broker.SimpleBrokerMessageHandler; import org.springframework.messaging.simp.stomp.StompBrokerRelayMessageHandler; +import org.springframework.util.AntPathMatcher; import org.springframework.util.Assert; /** * A registry for configuring message broker options. * * @author Rossen Stoyanchev + * @author Sebastien Deleuze * @since 4.0 */ public class MessageBrokerRegistry { @@ -47,6 +49,7 @@ public class MessageBrokerRegistry { private ChannelRegistration brokerChannelRegistration = new ChannelRegistration(); + private String defaultSeparator; public MessageBrokerRegistry(SubscribableChannel clientInboundChannel, MessageChannel clientOutboundChannel) { Assert.notNull(clientInboundChannel); @@ -119,12 +122,24 @@ public class MessageBrokerRegistry { return this.brokerChannelRegistration; } + /** + * Customize the default separator used for destination patterns matching/combining. + * It can be used to configure "." as the default separator, since it is used in most + * STOMP broker relay, enabling destination patterns like "/topic/PRICE.STOCK.**". + *

The default separator is "/". + */ + public MessageBrokerRegistry defaultSeparator(String defaultSeparator) { + this.defaultSeparator = defaultSeparator; + return this; + } + protected SimpleBrokerMessageHandler getSimpleBroker(SubscribableChannel brokerChannel) { if ((this.simpleBrokerRegistration == null) && (this.brokerRelayRegistration == null)) { enableSimpleBroker(); } if (this.simpleBrokerRegistration != null) { - return this.simpleBrokerRegistration.getMessageHandler(brokerChannel); + AntPathMatcher pathMatcher = new AntPathMatcher(this.defaultSeparator); + return this.simpleBrokerRegistration.getMessageHandler(brokerChannel, pathMatcher); } return null; } @@ -148,4 +163,9 @@ public class MessageBrokerRegistry { protected ChannelRegistration getBrokerChannelRegistration() { return this.brokerChannelRegistration; } + + protected String getDefaultSeparator() { + return this.defaultSeparator; + } + } diff --git a/spring-messaging/src/main/java/org/springframework/messaging/simp/config/SimpleBrokerRegistration.java b/spring-messaging/src/main/java/org/springframework/messaging/simp/config/SimpleBrokerRegistration.java index 2c683ebe342..5784fd90223 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/simp/config/SimpleBrokerRegistration.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/simp/config/SimpleBrokerRegistration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -19,11 +19,13 @@ package org.springframework.messaging.simp.config; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.SubscribableChannel; import org.springframework.messaging.simp.broker.SimpleBrokerMessageHandler; +import org.springframework.util.PathMatcher; /** * Registration class for configuring a {@link SimpleBrokerMessageHandler}. * * @author Rossen Stoyanchev + * @author Sebastien Deleuze * @since 4.0 */ public class SimpleBrokerRegistration extends AbstractBrokerRegistration { @@ -36,10 +38,9 @@ public class SimpleBrokerRegistration extends AbstractBrokerRegistration { } - @Override - protected SimpleBrokerMessageHandler getMessageHandler(SubscribableChannel brokerChannel) { + protected SimpleBrokerMessageHandler getMessageHandler(SubscribableChannel brokerChannel, PathMatcher pathMatcher) { return new SimpleBrokerMessageHandler(getClientInboundChannel(), - getClientOutboundChannel(), brokerChannel, getDestinationPrefixes()); + getClientOutboundChannel(), brokerChannel, getDestinationPrefixes(), pathMatcher); } } diff --git a/spring-messaging/src/test/java/org/springframework/messaging/handler/DestinationPatternsMessageConditionTests.java b/spring-messaging/src/test/java/org/springframework/messaging/handler/DestinationPatternsMessageConditionTests.java index a20abb45458..c18dc4deec9 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/handler/DestinationPatternsMessageConditionTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/handler/DestinationPatternsMessageConditionTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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. @@ -18,18 +18,36 @@ package org.springframework.messaging.handler; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; import org.springframework.messaging.Message; import org.springframework.messaging.support.MessageBuilder; +import org.junit.runners.Parameterized.Parameters; +import org.junit.runners.Parameterized.Parameter; +import org.springframework.util.AntPathMatcher; + +import java.util.Arrays; + import static org.junit.Assert.*; /** * Unit tests for {@link DestinationPatternsMessageCondition}. * * @author Rossen Stoyanchev + * @author Sebastien Deleuze */ +@RunWith(Parameterized.class) public class DestinationPatternsMessageConditionTests { + @Parameter(0) + public String pathSeparator; + + @Parameters + public static Iterable arguments() { + return Arrays.asList(new Object[][]{{"/"}, {"."}}); + } + @Test public void prependSlash() { DestinationPatternsMessageCondition c = condition("foo"); @@ -47,20 +65,21 @@ public class DestinationPatternsMessageConditionTests { @Test public void combineEmptySets() { DestinationPatternsMessageCondition c1 = condition(); - DestinationPatternsMessageCondition c2 = condition(); + DestinationPatternsMessageCondition c2 = suffixCondition(); assertEquals(condition(""), c1.combine(c2)); } @Test public void combineOnePatternWithEmptySet() { - DestinationPatternsMessageCondition c1 = condition("/type1", "/type2"); - DestinationPatternsMessageCondition c2 = condition(); + DestinationPatternsMessageCondition c1 = condition("/type1", + pathSeparator + "type2"); + DestinationPatternsMessageCondition c2 = suffixCondition(); - assertEquals(condition("/type1", "/type2"), c1.combine(c2)); + assertEquals(condition("/type1", pathSeparator + "type2"), c1.combine(c2)); c1 = condition(); - c2 = condition("/method1", "/method2"); + c2 = suffixCondition("/method1", "/method2"); assertEquals(condition("/method1", "/method2"), c1.combine(c2)); } @@ -68,10 +87,12 @@ public class DestinationPatternsMessageConditionTests { @Test public void combineMultiplePatterns() { DestinationPatternsMessageCondition c1 = condition("/t1", "/t2"); - DestinationPatternsMessageCondition c2 = condition("/m1", "/m2"); + DestinationPatternsMessageCondition c2 = suffixCondition(pathSeparator + "m1", + pathSeparator + "m2"); - assertEquals(new DestinationPatternsMessageCondition( - "/t1/m1", "/t1/m2", "/t2/m1", "/t2/m2"), c1.combine(c2)); + assertEquals( + condition("/t1" + pathSeparator + "m1", "/t1" + pathSeparator + "m2", + "/t2" + pathSeparator + "m1", "/t2" + pathSeparator + "m2"), c1.combine(c2)); } @Test @@ -84,35 +105,40 @@ public class DestinationPatternsMessageConditionTests { @Test public void matchPattern() { - DestinationPatternsMessageCondition condition = condition("/foo/*"); - DestinationPatternsMessageCondition match = condition.getMatchingCondition(messageTo("/foo/bar")); + DestinationPatternsMessageCondition condition = condition( + "/foo" + pathSeparator + "*"); + DestinationPatternsMessageCondition match = condition.getMatchingCondition(messageTo("/foo" + pathSeparator + "bar")); assertNotNull(match); } @Test public void matchSortPatterns() { - DestinationPatternsMessageCondition condition = condition("/**", "/foo/bar", "/foo/*"); - DestinationPatternsMessageCondition match = condition.getMatchingCondition(messageTo("/foo/bar")); - DestinationPatternsMessageCondition expected = condition("/foo/bar", "/foo/*", "/**"); + DestinationPatternsMessageCondition condition = suffixCondition( + pathSeparator + "**", pathSeparator + "foo" + pathSeparator + "bar", + pathSeparator + "foo" + pathSeparator + "*"); + DestinationPatternsMessageCondition match = condition.getMatchingCondition(messageTo(pathSeparator + "foo" + pathSeparator + "bar")); + DestinationPatternsMessageCondition expected = suffixCondition( + pathSeparator + "foo" + pathSeparator + "bar", + pathSeparator + "foo" + pathSeparator + "*", pathSeparator + "**"); assertEquals(expected, match); } @Test public void compareEqualPatterns() { - DestinationPatternsMessageCondition c1 = condition("/foo*"); - DestinationPatternsMessageCondition c2 = condition("/foo*"); + DestinationPatternsMessageCondition c1 = suffixCondition(pathSeparator + "foo*"); + DestinationPatternsMessageCondition c2 = suffixCondition(pathSeparator + "foo*"); - assertEquals(0, c1.compareTo(c2, messageTo("/foo"))); + assertEquals(0, c1.compareTo(c2, messageTo(pathSeparator + "foo"))); } @Test public void comparePatternSpecificity() { - DestinationPatternsMessageCondition c1 = condition("/fo*"); - DestinationPatternsMessageCondition c2 = condition("/foo"); + DestinationPatternsMessageCondition c1 = suffixCondition(pathSeparator + "fo*"); + DestinationPatternsMessageCondition c2 = suffixCondition(pathSeparator + "foo"); - assertEquals(1, c1.compareTo(c2, messageTo("/foo"))); + assertEquals(1, c1.compareTo(c2, messageTo(pathSeparator + "foo"))); } @Test @@ -130,7 +156,11 @@ public class DestinationPatternsMessageConditionTests { private DestinationPatternsMessageCondition condition(String... patterns) { - return new DestinationPatternsMessageCondition(patterns); + return new DestinationPatternsMessageCondition(patterns, new AntPathMatcher(this.pathSeparator)); + } + + private DestinationPatternsMessageCondition suffixCondition(String... patterns) { + return new DestinationPatternsMessageCondition(patterns, new AntPathMatcher(this.pathSeparator), false); } private Message messageTo(String destination) { diff --git a/spring-messaging/src/test/java/org/springframework/messaging/simp/config/MessageBrokerConfigurationTests.java b/spring-messaging/src/test/java/org/springframework/messaging/simp/config/MessageBrokerConfigurationTests.java index 848b11e6faf..c3fdb9902ef 100644 --- a/spring-messaging/src/test/java/org/springframework/messaging/simp/config/MessageBrokerConfigurationTests.java +++ b/spring-messaging/src/test/java/org/springframework/messaging/simp/config/MessageBrokerConfigurationTests.java @@ -27,6 +27,7 @@ import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; +import org.springframework.beans.DirectFieldAccessor; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -39,6 +40,7 @@ import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.messaging.simp.SimpMessageType; import org.springframework.messaging.simp.annotation.SubscribeMapping; import org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler; +import org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry; import org.springframework.messaging.simp.broker.SimpleBrokerMessageHandler; import org.springframework.messaging.simp.user.UserDestinationMessageHandler; import org.springframework.messaging.simp.user.UserSessionRegistry; @@ -52,6 +54,7 @@ import org.springframework.messaging.support.ExecutorSubscribableChannel; import org.springframework.messaging.support.MessageBuilder; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Controller; +import org.springframework.util.AntPathMatcher; import org.springframework.util.MimeTypeUtils; import org.springframework.validation.Errors; import org.springframework.validation.Validator; @@ -64,6 +67,7 @@ import static org.junit.Assert.*; * * @author Rossen Stoyanchev * @author Brian Clozel + * @author Sebastien Deleuze */ public class MessageBrokerConfigurationTests { @@ -75,6 +79,8 @@ public class MessageBrokerConfigurationTests { private AnnotationConfigApplicationContext customChannelContext; + private AnnotationConfigApplicationContext customMatchingContext; + @Before public void setupOnce() { @@ -94,6 +100,10 @@ public class MessageBrokerConfigurationTests { this.customChannelContext = new AnnotationConfigApplicationContext(); this.customChannelContext.register(CustomChannelConfig.class); this.customChannelContext.refresh(); + + this.customMatchingContext = new AnnotationConfigApplicationContext(); + this.customMatchingContext.register(CustomMatchingSimpleBrokerConfig.class); + this.customMatchingContext.refresh(); } @@ -396,6 +406,20 @@ public class MessageBrokerConfigurationTests { assertThat(messageHandler.getValidator(), Matchers.notNullValue(Validator.class)); } + @Test + public void customMatching() { + SimpleBrokerMessageHandler brokerHandler = this.customMatchingContext.getBean(SimpleBrokerMessageHandler.class); + DefaultSubscriptionRegistry subscriptionRegistry = (DefaultSubscriptionRegistry)brokerHandler.getSubscriptionRegistry(); + AntPathMatcher pathMatcher = (AntPathMatcher)subscriptionRegistry.getPathMatcher(); + DirectFieldAccessor accessor = new DirectFieldAccessor(pathMatcher); + assertEquals(".", accessor.getPropertyValue("pathSeparator")); + + SimpAnnotationMethodMessageHandler messageHandler = customMatchingContext.getBean(SimpAnnotationMethodMessageHandler.class); + pathMatcher = (AntPathMatcher)messageHandler.getPathMatcher(); + accessor = new DirectFieldAccessor(pathMatcher); + assertEquals(".", accessor.getPropertyValue("pathSeparator")); + } + @Controller static class TestController { @@ -479,6 +503,15 @@ public class MessageBrokerConfigurationTests { } } + @Configuration + static class CustomMatchingSimpleBrokerConfig extends SimpleBrokerConfig { + + @Override + public void configureMessageBroker(MessageBrokerRegistry registry) { + registry.defaultSeparator(".").enableSimpleBroker("/topic", "/queue"); + } + } + private static class TestChannel extends ExecutorSubscribableChannel { diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java b/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java index c2c9c3216b5..e35e6a632e4 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java @@ -21,10 +21,9 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import org.springframework.beans.factory.config.CustomScopeConfigurer; -import org.springframework.messaging.simp.SimpSessionScope; import org.w3c.dom.Element; +import org.springframework.beans.factory.config.CustomScopeConfigurer; import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.ConstructorArgumentValues; @@ -42,6 +41,7 @@ import org.springframework.messaging.converter.DefaultContentTypeResolver; import org.springframework.messaging.converter.MappingJackson2MessageConverter; import org.springframework.messaging.converter.StringMessageConverter; import org.springframework.messaging.simp.SimpMessagingTemplate; +import org.springframework.messaging.simp.SimpSessionScope; import org.springframework.messaging.simp.annotation.support.SimpAnnotationMethodMessageHandler; import org.springframework.messaging.simp.user.DefaultUserDestinationResolver; import org.springframework.messaging.simp.user.DefaultUserSessionRegistry; @@ -50,6 +50,7 @@ import org.springframework.messaging.simp.user.UserDestinationMessageHandler; import org.springframework.messaging.simp.stomp.StompBrokerRelayMessageHandler; import org.springframework.messaging.support.ExecutorSubscribableChannel; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.util.AntPathMatcher; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.MimeTypeUtils; @@ -329,6 +330,10 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { if (simpleBrokerElem != null) { String prefix = simpleBrokerElem.getAttribute("prefix"); cavs.addIndexedArgumentValue(3, Arrays.asList(StringUtils.tokenizeToStringArray(prefix, ","))); + String defaultSeparator = messageBrokerElement.getAttribute("default-separator"); + if (!defaultSeparator.isEmpty()) { + cavs.addIndexedArgumentValue(4, new AntPathMatcher(defaultSeparator)); + } brokerDef = new RootBeanDefinition(SimpleBrokerMessageHandler.class, cavs, null); } else if (brokerRelayElem != null) { @@ -452,6 +457,11 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { RootBeanDefinition annotationMethodMessageHandlerDef = new RootBeanDefinition(SimpAnnotationMethodMessageHandler.class, cavs, mpvs); + String defaultSeparator = messageBrokerElement.getAttribute("default-separator"); + if (!defaultSeparator.isEmpty()) { + annotationMethodMessageHandlerDef.getPropertyValues().add("pathMatcher", new AntPathMatcher(defaultSeparator)); + } + registerBeanDef(annotationMethodMessageHandlerDef, parserCxt, source); } diff --git a/spring-websocket/src/main/resources/META-INF/spring.schemas b/spring-websocket/src/main/resources/META-INF/spring.schemas index 21071f78efc..5bcbadcb44b 100644 --- a/spring-websocket/src/main/resources/META-INF/spring.schemas +++ b/spring-websocket/src/main/resources/META-INF/spring.schemas @@ -1,2 +1,3 @@ http\://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd=org/springframework/web/socket/config/spring-websocket-4.0.xsd -http\://www.springframework.org/schema/websocket/spring-websocket.xsd=org/springframework/web/socket/config/spring-websocket-4.0.xsd +http\://www.springframework.org/schema/websocket/spring-websocket-4.1.xsd=org/springframework/web/socket/config/spring-websocket-4.1.xsd +http\://www.springframework.org/schema/websocket/spring-websocket.xsd=org/springframework/web/socket/config/spring-websocket-4.1.xsd diff --git a/spring-websocket/src/main/resources/org/springframework/web/socket/config/spring-websocket-4.1.xsd b/spring-websocket/src/main/resources/org/springframework/web/socket/config/spring-websocket-4.1.xsd new file mode 100644 index 00000000000..70edfe0dd0c --- /dev/null +++ b/spring-websocket/src/main/resources/org/springframework/web/socket/config/spring-websocket-4.1.xsd @@ -0,0 +1,710 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParserTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParserTests.java index 4accbdce9f9..d77b650bcff 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParserTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParserTests.java @@ -182,6 +182,10 @@ public class MessageBrokerBeanDefinitionParserTests { } assertNotNull(this.appContext.getBean("webSocketScopeConfigurer", CustomScopeConfigurer.class)); + + DirectFieldAccessor subscriptionRegistryAccessor = new DirectFieldAccessor(brokerMessageHandler.getSubscriptionRegistry()); + String pathSeparator = (String)new DirectFieldAccessor(subscriptionRegistryAccessor.getPropertyValue("pathMatcher")).getPropertyValue("pathSeparator"); + assertEquals(".", pathSeparator); } @Test @@ -285,6 +289,10 @@ public class MessageBrokerBeanDefinitionParserTests { ContentTypeResolver resolver = ((MappingJackson2MessageConverter) converters.get(2)).getContentTypeResolver(); assertEquals(MimeTypeUtils.APPLICATION_JSON, ((DefaultContentTypeResolver) resolver).getDefaultMimeType()); + + DirectFieldAccessor handlerAccessor = new DirectFieldAccessor(annotationMethodMessageHandler); + String pathSeparator = (String)new DirectFieldAccessor(handlerAccessor.getPropertyValue("pathMatcher")).getPropertyValue("pathSeparator"); + assertEquals(".", pathSeparator); } @Test diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-converters-defaults-off.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-converters-defaults-off.xml index c2c6d5e4358..d136c574a8c 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-converters-defaults-off.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-converters-defaults-off.xml @@ -2,7 +2,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:websocket="http://www.springframework.org/schema/websocket" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd"> + http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.1.xsd"> diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-converters.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-converters.xml index 83db0823992..d139a8b5f4a 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-converters.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-converters.xml @@ -2,7 +2,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:websocket="http://www.springframework.org/schema/websocket" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd"> + http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.1.xsd"> diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-customchannels-default-executor.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-customchannels-default-executor.xml index 4c8de3eeded..bbc598e85cb 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-customchannels-default-executor.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-customchannels-default-executor.xml @@ -3,7 +3,7 @@ xmlns:websocket="http://www.springframework.org/schema/websocket" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd"> + http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.1.xsd"> diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-customchannels.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-customchannels.xml index bed4735260e..5b7b61a44e6 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-customchannels.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-customchannels.xml @@ -2,7 +2,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:websocket="http://www.springframework.org/schema/websocket" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd"> + http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.1.xsd"> diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-relay.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-relay.xml index 4a6f0fa85c4..892c69efaac 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-relay.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-relay.xml @@ -2,7 +2,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:websocket="http://www.springframework.org/schema/websocket" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd"> + http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.1.xsd"> diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-simple.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-simple.xml index 045c47e2961..bd82c4b29ac 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-simple.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-simple.xml @@ -2,9 +2,9 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:websocket="http://www.springframework.org/schema/websocket" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd"> + http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.1.xsd"> - + diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-attributes.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-attributes.xml index e84d9fd77a5..dd5e4ea8387 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-attributes.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-attributes.xml @@ -3,7 +3,7 @@ xmlns:websocket="http://www.springframework.org/schema/websocket" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd"> + http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.1.xsd"> diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs-attributes.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs-attributes.xml index b8cb777b799..0c3ac67877b 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs-attributes.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs-attributes.xml @@ -3,7 +3,7 @@ xmlns:websocket="http://www.springframework.org/schema/websocket" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd"> + http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.1.xsd"> diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs.xml index a7f75dbada5..05b6732a290 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs.xml @@ -3,7 +3,7 @@ xmlns:websocket="http://www.springframework.org/schema/websocket" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd"> + http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.1.xsd"> diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers.xml index 4a79d2a5a39..9217975776f 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers.xml @@ -3,7 +3,7 @@ xmlns:websocket="http://www.springframework.org/schema/websocket" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd - http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.0.xsd"> + http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.1.xsd">