Skip to content

Commit 752832a

Browse files
committed
SPR-5731 - @controller method order effects @RequestMapping behavior in ways not expected
1 parent fbd921f commit 752832a

File tree

2 files changed

+21
-18
lines changed

2 files changed

+21
-18
lines changed

org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerAdapter.java

+13-11
Original file line numberDiff line numberDiff line change
@@ -423,10 +423,11 @@ public Method resolveHandlerMethod(HttpServletRequest request) throws ServletExc
423423
if (mappingInfo.paths.length > 0) {
424424
List<String> matchedPaths = new ArrayList<String>(mappingInfo.paths.length);
425425
for (String methodLevelPattern : mappingInfo.paths) {
426-
if (isPathMatch(methodLevelPattern, lookupPath)) {
426+
String matchedPattern = getMatchedPattern(methodLevelPattern, lookupPath);
427+
if (matchedPattern != null) {
427428
if (mappingInfo.matches(request)) {
428429
match = true;
429-
matchedPaths.add(methodLevelPattern);
430+
matchedPaths.add(matchedPattern);
430431
}
431432
else {
432433
for (RequestMethod requestMethod : mappingInfo.methods) {
@@ -437,7 +438,7 @@ public Method resolveHandlerMethod(HttpServletRequest request) throws ServletExc
437438
}
438439
}
439440
Collections.sort(matchedPaths, pathComparator);
440-
mappingInfo.matchedPaths = matchedPaths.toArray(new String[matchedPaths.size()]);
441+
mappingInfo.matchedPaths = matchedPaths;
441442
}
442443
else {
443444
// No paths specified: parameter match sufficient.
@@ -485,8 +486,9 @@ public Method resolveHandlerMethod(HttpServletRequest request) throws ServletExc
485486
new RequestMappingInfoComparator(pathComparator);
486487
Collections.sort(matches, requestMappingInfoComparator);
487488
RequestMappingInfo bestMappingMatch = matches.get(0);
488-
if (bestMappingMatch.matchedPaths.length > 0) {
489-
extractHandlerMethodUriTemplates(bestMappingMatch.matchedPaths[0], lookupPath, request);
489+
String bestMatchedPath = bestMappingMatch.bestMatchedPath();
490+
if (bestMatchedPath != null) {
491+
extractHandlerMethodUriTemplates(bestMatchedPath, lookupPath, request);
490492
}
491493
return targetHandlerMethods.get(bestMappingMatch);
492494
}
@@ -502,10 +504,10 @@ public Method resolveHandlerMethod(HttpServletRequest request) throws ServletExc
502504
}
503505
}
504506

505-
private boolean isPathMatch(String methodLevelPattern, String lookupPath) {
507+
private String getMatchedPattern(String methodLevelPattern, String lookupPath) {
506508
if ((!hasTypeLevelMapping() || ObjectUtils.isEmpty(getTypeLevelMapping().value())) &&
507509
isPathMatchInternal(methodLevelPattern, lookupPath)) {
508-
return true;
510+
return methodLevelPattern;
509511
}
510512
if (hasTypeLevelMapping()) {
511513
String[] typeLevelPatterns = getTypeLevelMapping().value();
@@ -515,12 +517,12 @@ private boolean isPathMatch(String methodLevelPattern, String lookupPath) {
515517
}
516518
String combinedPattern = pathMatcher.combine(typeLevelPattern, methodLevelPattern);
517519
if (isPathMatchInternal(combinedPattern, lookupPath)) {
518-
return true;
520+
return combinedPattern;
519521
}
520522
}
521523

522524
}
523-
return false;
525+
return null;
524526
}
525527

526528
private boolean isPathMatchInternal(String pattern, String lookupPath) {
@@ -756,7 +758,7 @@ static class RequestMappingInfo {
756758

757759
String[] paths = new String[0];
758760

759-
String[] matchedPaths = new String[0];
761+
List<String> matchedPaths = Collections.emptyList();
760762

761763
RequestMethod[] methods = new RequestMethod[0];
762764

@@ -765,7 +767,7 @@ static class RequestMappingInfo {
765767
String[] headers = new String[0];
766768

767769
String bestMatchedPath() {
768-
return matchedPaths.length > 0 ? matchedPaths[0] : null;
770+
return matchedPaths.isEmpty() ? null : matchedPaths.get(0);
769771
}
770772

771773
public boolean matches(HttpServletRequest request) {

org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/annotation/UriTemplateServletAnnotationControllerTests.java

+8-7
Original file line numberDiff line numberDiff line change
@@ -264,20 +264,21 @@ public void handle(@PathVariable("hotel") String hotel, @PathVariable int bookin
264264
}
265265

266266
@Controller
267+
@RequestMapping("/hotels")
267268
public static class AmbiguousUriTemplateController {
268269

269-
@RequestMapping("/hotels/new")
270-
public void handleSpecific(Writer writer) throws IOException {
271-
writer.write("specific");
272-
}
273-
274-
@RequestMapping("/hotels/{hotel}")
270+
@RequestMapping("/{hotel}")
275271
public void handleVars(@PathVariable("hotel") String hotel, Writer writer) throws IOException {
276272
assertEquals("Invalid path variable value", "42", hotel);
277273
writer.write("variables");
278274
}
279275

280-
@RequestMapping("/hotels/*")
276+
@RequestMapping("/new")
277+
public void handleSpecific(Writer writer) throws IOException {
278+
writer.write("specific");
279+
}
280+
281+
@RequestMapping("/*")
281282
public void handleWildCard(Writer writer) throws IOException {
282283
writer.write("wildcard");
283284
}

0 commit comments

Comments
 (0)