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:
parent
b6dff79bb0
commit
0650a6d471
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue