From 5787fc16fbca3d1e878a6c7dcc3fd6f8a2dff870 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Thu, 20 Jun 2019 20:23:04 +0200 Subject: [PATCH] PathPatternRouteMatcher should use custom separator Prior to this commit, the `PathPatternRouteMatcher` would always use the default path pattern separator when parsing incoming route strings to `RouteMatcher.Route` instances. When the `PathPatternRouteMatcher` is configured with a `PathPatternParser` that has a custom separator (e.g., `.`), then the matching algorithm can't match routes against parsed patterns. This commit ensures that the route matcher uses the configured separator at all times. Fixes gh-23167 --- .../util/pattern/PathPatternRouteMatcher.java | 5 +- .../pattern/PathPatternRouteMatcherTest.java | 49 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternRouteMatcherTest.java diff --git a/spring-web/src/main/java/org/springframework/web/util/pattern/PathPatternRouteMatcher.java b/spring-web/src/main/java/org/springframework/web/util/pattern/PathPatternRouteMatcher.java index 4dad70eb4f..514f0ab615 100644 --- a/spring-web/src/main/java/org/springframework/web/util/pattern/PathPatternRouteMatcher.java +++ b/spring-web/src/main/java/org/springframework/web/util/pattern/PathPatternRouteMatcher.java @@ -36,18 +36,21 @@ public class PathPatternRouteMatcher implements RouteMatcher { private final PathPatternParser parser; + private final String separator; + private final Map pathPatternCache = new ConcurrentHashMap<>(); public PathPatternRouteMatcher(PathPatternParser parser) { Assert.notNull(parser, "PathPatternParser must not be null"); this.parser = parser; + this.separator = String.valueOf(parser.getSeparator()); } @Override public Route parseRoute(String routeValue) { - return new PathContainerRoute(PathContainer.parsePath(routeValue)); + return new PathContainerRoute(PathContainer.parsePath(routeValue, this.separator)); } @Override diff --git a/spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternRouteMatcherTest.java b/spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternRouteMatcherTest.java new file mode 100644 index 0000000000..da806a823b --- /dev/null +++ b/spring-web/src/test/java/org/springframework/web/util/pattern/PathPatternRouteMatcherTest.java @@ -0,0 +1,49 @@ +/* + * Copyright 2002-2019 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.util.pattern; + +import org.junit.Test; + +import org.springframework.util.RouteMatcher; + +import static org.assertj.core.api.Assertions.assertThat; + + +/** + * Tests for the {@link PathPatternRouteMatcher} + * @author Brian Clozel + */ +public class PathPatternRouteMatcherTest { + + PathPatternRouteMatcher routeMatcher = new PathPatternRouteMatcher(new PathPatternParser()); + + @Test + public void matchRoute() { + RouteMatcher.Route route = routeMatcher.parseRoute("/projects/spring-framework"); + assertThat(routeMatcher.match("/projects/{name}", route)).isTrue(); + } + + @Test + public void matchRouteCustomSeparator() { + PathPatternParser pathPatternParser = new PathPatternParser(); + pathPatternParser.setSeparator('.'); + PathPatternRouteMatcher routeMatcher = new PathPatternRouteMatcher(pathPatternParser); + RouteMatcher.Route route = routeMatcher.parseRoute("projects.spring-framework"); + assertThat(routeMatcher.match("projects.{name}", route)).isTrue(); + } + +}