SPR-5731 - @Controller method order effects @RequestMapping behavior in ways not expected

git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@1141 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
Arjen Poutsma 2009-05-11 10:34:56 +00:00
parent b6dff79bb0
commit 0650a6d471
2 changed files with 21 additions and 18 deletions

View File

@ -423,10 +423,11 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
if (mappingInfo.paths.length > 0) { if (mappingInfo.paths.length > 0) {
List<String> matchedPaths = new ArrayList<String>(mappingInfo.paths.length); List<String> matchedPaths = new ArrayList<String>(mappingInfo.paths.length);
for (String methodLevelPattern : mappingInfo.paths) { for (String methodLevelPattern : mappingInfo.paths) {
if (isPathMatch(methodLevelPattern, lookupPath)) { String matchedPattern = getMatchedPattern(methodLevelPattern, lookupPath);
if (matchedPattern != null) {
if (mappingInfo.matches(request)) { if (mappingInfo.matches(request)) {
match = true; match = true;
matchedPaths.add(methodLevelPattern); matchedPaths.add(matchedPattern);
} }
else { else {
for (RequestMethod requestMethod : mappingInfo.methods) { for (RequestMethod requestMethod : mappingInfo.methods) {
@ -437,7 +438,7 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
} }
} }
Collections.sort(matchedPaths, pathComparator); Collections.sort(matchedPaths, pathComparator);
mappingInfo.matchedPaths = matchedPaths.toArray(new String[matchedPaths.size()]); mappingInfo.matchedPaths = matchedPaths;
} }
else { else {
// No paths specified: parameter match sufficient. // No paths specified: parameter match sufficient.
@ -485,8 +486,9 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
new RequestMappingInfoComparator(pathComparator); new RequestMappingInfoComparator(pathComparator);
Collections.sort(matches, requestMappingInfoComparator); Collections.sort(matches, requestMappingInfoComparator);
RequestMappingInfo bestMappingMatch = matches.get(0); RequestMappingInfo bestMappingMatch = matches.get(0);
if (bestMappingMatch.matchedPaths.length > 0) { String bestMatchedPath = bestMappingMatch.bestMatchedPath();
extractHandlerMethodUriTemplates(bestMappingMatch.matchedPaths[0], lookupPath, request); if (bestMatchedPath != null) {
extractHandlerMethodUriTemplates(bestMatchedPath, lookupPath, request);
} }
return targetHandlerMethods.get(bestMappingMatch); return targetHandlerMethods.get(bestMappingMatch);
} }
@ -502,10 +504,10 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
} }
} }
private boolean isPathMatch(String methodLevelPattern, String lookupPath) { private String getMatchedPattern(String methodLevelPattern, String lookupPath) {
if ((!hasTypeLevelMapping() || ObjectUtils.isEmpty(getTypeLevelMapping().value())) && if ((!hasTypeLevelMapping() || ObjectUtils.isEmpty(getTypeLevelMapping().value())) &&
isPathMatchInternal(methodLevelPattern, lookupPath)) { isPathMatchInternal(methodLevelPattern, lookupPath)) {
return true; return methodLevelPattern;
} }
if (hasTypeLevelMapping()) { if (hasTypeLevelMapping()) {
String[] typeLevelPatterns = getTypeLevelMapping().value(); String[] typeLevelPatterns = getTypeLevelMapping().value();
@ -515,12 +517,12 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
} }
String combinedPattern = pathMatcher.combine(typeLevelPattern, methodLevelPattern); String combinedPattern = pathMatcher.combine(typeLevelPattern, methodLevelPattern);
if (isPathMatchInternal(combinedPattern, lookupPath)) { if (isPathMatchInternal(combinedPattern, lookupPath)) {
return true; return combinedPattern;
} }
} }
} }
return false; return null;
} }
private boolean isPathMatchInternal(String pattern, String lookupPath) { private boolean isPathMatchInternal(String pattern, String lookupPath) {
@ -756,7 +758,7 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
String[] paths = new String[0]; String[] paths = new String[0];
String[] matchedPaths = new String[0]; List<String> matchedPaths = Collections.emptyList();
RequestMethod[] methods = new RequestMethod[0]; RequestMethod[] methods = new RequestMethod[0];
@ -765,7 +767,7 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator implemen
String[] headers = new String[0]; String[] headers = new String[0];
String bestMatchedPath() { String bestMatchedPath() {
return matchedPaths.length > 0 ? matchedPaths[0] : null; return matchedPaths.isEmpty() ? null : matchedPaths.get(0);
} }
public boolean matches(HttpServletRequest request) { public boolean matches(HttpServletRequest request) {

View File

@ -264,20 +264,21 @@ public class UriTemplateServletAnnotationControllerTests {
} }
@Controller @Controller
@RequestMapping("/hotels")
public static class AmbiguousUriTemplateController { public static class AmbiguousUriTemplateController {
@RequestMapping("/hotels/new") @RequestMapping("/{hotel}")
public void handleSpecific(Writer writer) throws IOException {
writer.write("specific");
}
@RequestMapping("/hotels/{hotel}")
public void handleVars(@PathVariable("hotel") String hotel, Writer writer) throws IOException { public void handleVars(@PathVariable("hotel") String hotel, Writer writer) throws IOException {
assertEquals("Invalid path variable value", "42", hotel); assertEquals("Invalid path variable value", "42", hotel);
writer.write("variables"); writer.write("variables");
} }
@RequestMapping("/hotels/*") @RequestMapping("/new")
public void handleSpecific(Writer writer) throws IOException {
writer.write("specific");
}
@RequestMapping("/*")
public void handleWildCard(Writer writer) throws IOException { public void handleWildCard(Writer writer) throws IOException {
writer.write("wildcard"); writer.write("wildcard");
} }