diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java index 75ba08c540f..cc874c71456 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/handler/AbstractUrlHandlerMapping.java @@ -208,7 +208,7 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping { */ protected void validateHandler(Object handler, HttpServletRequest request) throws Exception { } - + /** * Build a handler object for the given raw handler, exposing the actual * handler, the {@link #PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE}, as well as diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerAdapter.java index 6a0ef788b8b..20dd1d07448 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerAdapter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerAdapter.java @@ -588,7 +588,8 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator if (!typeLevelPattern.startsWith("/")) { typeLevelPattern = "/" + typeLevelPattern; } - if (getMatchingPattern(typeLevelPattern, lookupPath) != null) { + boolean useSuffixPattern = useSuffixPattern(request); + if (getMatchingPattern(typeLevelPattern, lookupPath, useSuffixPattern) != null) { if (mappingInfo.matches(request)) { match = true; mappingInfo.addMatchedPattern(typeLevelPattern); @@ -675,6 +676,11 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator return (Boolean) request.getAttribute(HandlerMapping.INTROSPECT_TYPE_LEVEL_MAPPING); } + private boolean useSuffixPattern(HttpServletRequest request) { + Object value = request.getAttribute(DefaultAnnotationHandlerMapping.USE_DEFAULT_SUFFIX_PATTERN); + return (value != null) ? (Boolean) value : Boolean.TRUE; + } + /** * Determines the combined pattern for the given methodLevelPattern and path. *
Uses the following algorithm:
@@ -687,6 +693,7 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
*
*/
private String getCombinedPattern(String methodLevelPattern, String lookupPath, HttpServletRequest request) {
+ boolean useSuffixPattern = useSuffixPattern(request);
if (useTypeLevelMapping(request)) {
String[] typeLevelPatterns = getTypeLevelMapping().value();
for (String typeLevelPattern : typeLevelPatterns) {
@@ -694,7 +701,7 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
typeLevelPattern = "/" + typeLevelPattern;
}
String combinedPattern = pathMatcher.combine(typeLevelPattern, methodLevelPattern);
- String matchingPattern = getMatchingPattern(combinedPattern, lookupPath);
+ String matchingPattern = getMatchingPattern(combinedPattern, lookupPath, useSuffixPattern);
if (matchingPattern != null) {
return matchingPattern;
}
@@ -704,20 +711,20 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
String bestMatchingPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
if (StringUtils.hasText(bestMatchingPattern) && bestMatchingPattern.endsWith("*")) {
String combinedPattern = pathMatcher.combine(bestMatchingPattern, methodLevelPattern);
- String matchingPattern = getMatchingPattern(combinedPattern, lookupPath);
+ String matchingPattern = getMatchingPattern(combinedPattern, lookupPath, useSuffixPattern);
if (matchingPattern != null && !matchingPattern.equals(bestMatchingPattern)) {
return matchingPattern;
}
}
- return getMatchingPattern(methodLevelPattern, lookupPath);
+ return getMatchingPattern(methodLevelPattern, lookupPath, useSuffixPattern);
}
- private String getMatchingPattern(String pattern, String lookupPath) {
+ private String getMatchingPattern(String pattern, String lookupPath, boolean useSuffixPattern) {
if (pattern.equals(lookupPath)) {
return pattern;
}
boolean hasSuffix = pattern.indexOf('.') != -1;
- if (!hasSuffix) {
+ if (useSuffixPattern && !hasSuffix) {
String patternWithSuffix = pattern + ".*";
if (pathMatcher.match(patternWithSuffix, lookupPath)) {
return patternWithSuffix;
@@ -727,7 +734,7 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
return pattern;
}
boolean endsWithSlash = pattern.endsWith("/");
- if (!endsWithSlash) {
+ if (useSuffixPattern && !endsWithSlash) {
String patternWithSlash = pattern + "/";
if (pathMatcher.match(patternWithSlash, lookupPath)) {
return patternWithSlash;
@@ -1236,7 +1243,7 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
private int compareAcceptHeaders(RequestMappingInfo info1, RequestMappingInfo info2) {
List