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 65a2d64a198..76f4fe9467d 100644 --- a/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java +++ b/spring-core/src/main/java/org/springframework/util/AntPathMatcher.java @@ -317,10 +317,10 @@ public class AntPathMatcher implements PathMatcher { if (!StringUtils.hasText(pattern1) && !StringUtils.hasText(pattern2)) { return ""; } - else if (!StringUtils.hasText(pattern1)) { + if (!StringUtils.hasText(pattern1)) { return pattern2; } - else if (!StringUtils.hasText(pattern2)) { + if (!StringUtils.hasText(pattern2)) { return pattern1; } @@ -330,55 +330,37 @@ public class AntPathMatcher implements PathMatcher { // However /user + /user -> /usr/user ; /{foo} + /bar -> /{foo}/bar return pattern2; } - else if (pattern1.endsWith("/*")) { - if (pattern2.startsWith("/")) { - // /hotels/* + /booking -> /hotels/booking - return pattern1.substring(0, pattern1.length() - 1) + pattern2.substring(1); - } - else { - // /hotels/* + booking -> /hotels/booking - return pattern1.substring(0, pattern1.length() - 1) + pattern2; - } - } - else if (pattern1.endsWith("/**")) { - if (pattern2.startsWith("/")) { - // /hotels/** + /booking -> /hotels/**/booking - return pattern1 + pattern2; - } - else { - // /hotels/** + booking -> /hotels/**/booking - return pattern1 + "/" + pattern2; - } - } - else { - int dotPos1 = pattern1.indexOf('.'); - if (dotPos1 == -1 || pattern1ContainsUriVar) { - // simply concatenate the two patterns - if (pattern1.endsWith("/") || pattern2.startsWith("/")) { - return pattern1 + pattern2; - } - else { - return pattern1 + "/" + pattern2; - } - } - String fileName1 = pattern1.substring(0, dotPos1); - String extension1 = pattern1.substring(dotPos1); - String fileName2; - String extension2; - int dotPos2 = pattern2.indexOf('.'); - if (dotPos2 != -1) { - fileName2 = pattern2.substring(0, dotPos2); - extension2 = pattern2.substring(dotPos2); - } - else { - fileName2 = pattern2; - extension2 = ""; - } - String fileName = fileName1.endsWith("*") ? fileName2 : fileName1; - String extension = extension1.startsWith("*") ? extension2 : extension1; - return fileName + extension; + // /hotels/* + /booking -> /hotels/booking + // /hotels/* + booking -> /hotels/booking + if (pattern1.endsWith("/*")) { + return slashConcat(pattern1.substring(0, pattern1.length() - 2), pattern2); } + + // /hotels/** + /booking -> /hotels/**/booking + // /hotels/** + booking -> /hotels/**/booking + if (pattern1.endsWith("/**")) { + return slashConcat(pattern1, pattern2); + } + + int starDotPos1 = pattern1.indexOf("*."); + if (pattern1ContainsUriVar || starDotPos1 == -1) { + // simply concatenate the two patterns + return slashConcat(pattern1, pattern2); + } + String extension1 = pattern1.substring(starDotPos1 + 1); + int dotPos2 = pattern2.indexOf('.'); + String fileName2 = (dotPos2 == -1 ? pattern2 : pattern2.substring(0, dotPos2)); + String extension2 = (dotPos2 == -1 ? "" : pattern2.substring(dotPos2)); + String extension = extension1.startsWith("*") ? extension2 : extension1; + return fileName2 + extension; + } + + private String slashConcat(String path1, String path2) { + if (path1.endsWith("/") || path2.startsWith("/")) { + return path1 + path2; + } + return path1 + "/" + 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 05a98f405d4..dba4f3fcd18 100644 --- a/spring-core/src/test/java/org/springframework/util/AntPathMatcherTests.java +++ b/spring-core/src/test/java/org/springframework/util/AntPathMatcherTests.java @@ -399,6 +399,7 @@ public class AntPathMatcherTests { assertEquals("/hotels/**/booking", pathMatcher.combine("/hotels/**", "/booking")); assertEquals("/hotels/booking", pathMatcher.combine("/hotels", "/booking")); assertEquals("/hotels/booking", pathMatcher.combine("/hotels", "booking")); + assertEquals("/hotels/booking", pathMatcher.combine("/hotels/", "booking")); assertEquals("/hotels/{hotel}", pathMatcher.combine("/hotels/*", "{hotel}")); assertEquals("/hotels/**/{hotel}", pathMatcher.combine("/hotels/**", "{hotel}")); assertEquals("/hotels/{hotel}", pathMatcher.combine("/hotels", "{hotel}")); @@ -413,6 +414,7 @@ public class AntPathMatcherTests { assertEquals("/{foo}/bar", pathMatcher.combine("/{foo}", "/bar")); // SPR-8858 assertEquals("/user/user", pathMatcher.combine("/user", "/user")); // SPR-7970 assertEquals("/{foo:.*[^0-9].*}/edit/", pathMatcher.combine("/{foo:.*[^0-9].*}", "/edit/")); // SPR-10062 + assertEquals("/1.0/foo/test", pathMatcher.combine("/1.0", "/foo/test")); // SPR-10554 } @Test