SPR-6482 - @RequestMapping handled incorrectly when value contains "." (dot) character

This commit is contained in:
Arjen Poutsma 2009-12-07 13:59:07 +00:00
parent f36e8252c8
commit 976f920db2
4 changed files with 55 additions and 10 deletions

View File

@ -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();
}
}

View File

@ -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;

View File

@ -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();
}
}

View File

@ -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);
}