SPR-6482 - @RequestMapping handled incorrectly when value contains "." (dot) character
This commit is contained in:
parent
f36e8252c8
commit
976f920db2
|
|
@ -19,6 +19,8 @@ package org.springframework.util;
|
|||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* PathMatcher implementation for Ant-style path patterns. Examples are provided below.
|
||||
|
|
@ -44,6 +46,8 @@ import java.util.Map;
|
|||
*/
|
||||
public class AntPathMatcher implements PathMatcher {
|
||||
|
||||
private static final Pattern VARIABLE_PATTERN = Pattern.compile("\\{[^/]+?\\}");
|
||||
|
||||
/** Default path separator: "/" */
|
||||
public static final String DEFAULT_PATH_SEPARATOR = "/";
|
||||
|
||||
|
|
@ -396,23 +400,56 @@ public class AntPathMatcher implements PathMatcher {
|
|||
else if (pattern2EqualsPath) {
|
||||
return 1;
|
||||
}
|
||||
int wildCardCount1 = StringUtils.countOccurrencesOf(pattern1, "*");
|
||||
int wildCardCount2 = StringUtils.countOccurrencesOf(pattern2, "*");
|
||||
int wildCardCount1 = getWildCardCount(pattern1);
|
||||
int wildCardCount2 = getWildCardCount(pattern2);
|
||||
|
||||
int bracketCount1 = StringUtils.countOccurrencesOf(pattern1, "{");
|
||||
int bracketCount2 = StringUtils.countOccurrencesOf(pattern2, "{");
|
||||
|
||||
int totalCount1 = wildCardCount1 + bracketCount1;
|
||||
int totalCount2 = wildCardCount2 + bracketCount2;
|
||||
|
||||
if (totalCount1 != totalCount2) {
|
||||
return totalCount1 - totalCount2;
|
||||
}
|
||||
|
||||
int pattern1Length = getPatternLength(pattern1);
|
||||
int pattern2Length = getPatternLength(pattern2);
|
||||
|
||||
if (pattern1Length != pattern2Length) {
|
||||
return pattern2Length - pattern1Length;
|
||||
}
|
||||
|
||||
if (wildCardCount1 < wildCardCount2) {
|
||||
return -1;
|
||||
}
|
||||
else if (wildCardCount2 < wildCardCount1) {
|
||||
return 1;
|
||||
}
|
||||
int bracketCount1 = StringUtils.countOccurrencesOf(pattern1, "{");
|
||||
int bracketCount2 = StringUtils.countOccurrencesOf(pattern2, "{");
|
||||
|
||||
if (bracketCount1 < bracketCount2) {
|
||||
return -1;
|
||||
}
|
||||
else if (bracketCount2 < bracketCount1) {
|
||||
return 1;
|
||||
}
|
||||
return pattern2.length() - pattern1.length();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private int getWildCardCount(String pattern) {
|
||||
if (pattern.endsWith(".*")) {
|
||||
pattern = pattern.substring(0, pattern.length() - 2);
|
||||
}
|
||||
return StringUtils.countOccurrencesOf(pattern, "*");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the given pattern, where template variables are considered to be 1 long.
|
||||
*/
|
||||
private int getPatternLength(String pattern) {
|
||||
Matcher m = VARIABLE_PATTERN.matcher(pattern);
|
||||
return m.replaceAll("#").length();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class AntPathStringMatcher {
|
|||
|
||||
private static final Pattern GLOB_PATTERN = Pattern.compile("\\?|\\*|\\{([^/]+?)\\}");
|
||||
|
||||
private static final String DEFAULT_VARIABLE_PATTERN = "([^\\.]*)";
|
||||
private static final String DEFAULT_VARIABLE_PATTERN = "(.*)";
|
||||
|
||||
private final Pattern pattern;
|
||||
|
||||
|
|
|
|||
|
|
@ -393,8 +393,8 @@ public class AntPathMatcherTests {
|
|||
assertEquals(-1, comparator.compare("/hotels/{hotel}", "/hotels/*"));
|
||||
assertEquals(1, comparator.compare("/hotels/*", "/hotels/{hotel}"));
|
||||
|
||||
assertEquals(-1, comparator.compare("/hotels/*", "/hotels/*/**"));
|
||||
assertEquals(1, comparator.compare("/hotels/*/**", "/hotels/*"));
|
||||
assertEquals(-2, comparator.compare("/hotels/*", "/hotels/*/**"));
|
||||
assertEquals(2, comparator.compare("/hotels/*/**", "/hotels/*"));
|
||||
|
||||
assertEquals(-1, comparator.compare("/hotels/new", "/hotels/new.*"));
|
||||
|
||||
|
|
@ -466,7 +466,6 @@ public class AntPathMatcherTests {
|
|||
paths.add("/hotels/*");
|
||||
paths.add("/hotels/{hotel}");
|
||||
paths.add("/hotels/new");
|
||||
Collections.shuffle(paths);
|
||||
Collections.sort(paths, comparator);
|
||||
assertEquals("/hotels/new", paths.get(0));
|
||||
assertEquals("/hotels/{hotel}", paths.get(1));
|
||||
|
|
@ -480,6 +479,15 @@ public class AntPathMatcherTests {
|
|||
assertEquals("/hotels/ne*", paths.get(0));
|
||||
assertEquals("/hotels/n*", paths.get(1));
|
||||
paths.clear();
|
||||
|
||||
comparator = pathMatcher.getPatternComparator("/hotels/new.html");
|
||||
paths.add("/hotels/new.*");
|
||||
paths.add("/hotels/{hotel}");
|
||||
Collections.shuffle(paths);
|
||||
Collections.sort(paths, comparator);
|
||||
assertEquals("/hotels/new.*", paths.get(0));
|
||||
assertEquals("/hotels/{hotel}", paths.get(1));
|
||||
paths.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -398,7 +398,7 @@ public class UriTemplateServletAnnotationControllerTests {
|
|||
@RequestMapping("hotels")
|
||||
public static class ImplicitSubPathController {
|
||||
|
||||
@RequestMapping("{hotel:.*}")
|
||||
@RequestMapping("{hotel}")
|
||||
public void handleHotel(@PathVariable String hotel, Writer writer) throws IOException {
|
||||
writer.write("test-" + hotel);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue