From 38a666077739de57b0b962aa0dd0ba40434a12c0 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 26 Jul 2011 08:26:09 +0000 Subject: [PATCH] SPR-8543 Fix issue in AnnotationMethodHandlerAdapter with extracting URI template variable from URL with file extension --- .../AnnotationMethodHandlerAdapter.java | 35 ++++++++++--------- ...plateServletAnnotationControllerTests.java | 13 +++++++ .../UriTemplateServletHandlerMethodTests.java | 14 ++++++++ .../ResourceHttpRequestHandlerTests.java | 9 +++++ .../servlet/resource/testsecret/secret.txt | 1 + 5 files changed, 56 insertions(+), 16 deletions(-) create mode 100644 org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/resource/testsecret/secret.txt diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerAdapter.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerAdapter.java index 30d29e1414..8796620b20 100644 --- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerAdapter.java +++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerAdapter.java @@ -27,6 +27,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; @@ -116,6 +117,7 @@ import org.springframework.web.servlet.mvc.multiaction.MethodNameResolver; import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException; import org.springframework.web.servlet.support.RequestContextUtils; import org.springframework.web.servlet.support.WebContentGenerator; +import org.springframework.web.util.UriTemplate; import org.springframework.web.util.UrlPathHelper; import org.springframework.web.util.WebUtils; @@ -587,7 +589,7 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator if (!typeLevelPattern.startsWith("/")) { typeLevelPattern = "/" + typeLevelPattern; } - if (isPathMatchInternal(typeLevelPattern, lookupPath)) { + if (getMatchingPattern(typeLevelPattern, lookupPath) != null) { if (mappingInfo.matches(request)) { match = true; mappingInfo.addMatchedPattern(typeLevelPattern); @@ -695,8 +697,9 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator typeLevelPattern = "/" + typeLevelPattern; } String combinedPattern = pathMatcher.combine(typeLevelPattern, methodLevelPattern); - if (isPathMatchInternal(combinedPattern, lookupPath)) { - return combinedPattern; + String matchingPattern = getMatchingPattern(combinedPattern, lookupPath); + if (matchingPattern != null) { + return matchingPattern; } } return null; @@ -704,30 +707,30 @@ 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); - if (!combinedPattern.equals(bestMatchingPattern) && - (isPathMatchInternal(combinedPattern, lookupPath))) { - return combinedPattern; + String matchingPattern = getMatchingPattern(combinedPattern, lookupPath); + if ((matchingPattern != null) && !matchingPattern.equals(bestMatchingPattern)) { + return matchingPattern; } } - if (isPathMatchInternal(methodLevelPattern, lookupPath)) { - return methodLevelPattern; - } - return null; + return getMatchingPattern(methodLevelPattern, lookupPath); } - private boolean isPathMatchInternal(String pattern, String lookupPath) { - if (pattern.equals(lookupPath) || pathMatcher.match(pattern, lookupPath)) { - return true; + private String getMatchingPattern(String pattern, String lookupPath) { + if (pattern.equals(lookupPath)) { + return pattern; } boolean hasSuffix = pattern.indexOf('.') != -1; if (!hasSuffix && pathMatcher.match(pattern + ".*", lookupPath)) { - return true; + return pattern + ".*"; + } + if (pathMatcher.match(pattern, lookupPath)) { + return pattern; } boolean endsWithSlash = pattern.endsWith("/"); if (!endsWithSlash && pathMatcher.match(pattern + "/", lookupPath)) { - return true; + return pattern + "/"; } - return false; + return null; } @SuppressWarnings("unchecked") diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/annotation/UriTemplateServletAnnotationControllerTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/annotation/UriTemplateServletAnnotationControllerTests.java index 2b436092e3..31489940e4 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/annotation/UriTemplateServletAnnotationControllerTests.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/annotation/UriTemplateServletAnnotationControllerTests.java @@ -340,6 +340,19 @@ public class UriTemplateServletAnnotationControllerTests { assertEquals("bar-bar", response.getContentAsString()); } + /* + * See SPR-8543 + */ + @Test + public void variableNamesWithUrlExtension() throws Exception { + initServlet(VariableNamesController.class); + + MockHttpServletRequest request = new MockHttpServletRequest("GET", "/test/foo.json"); + MockHttpServletResponse response = new MockHttpServletResponse(); + servlet.service(request, response); + assertEquals("foo-foo", response.getContentAsString()); + } + /* * See SPR-6906 */ diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/UriTemplateServletHandlerMethodTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/UriTemplateServletHandlerMethodTests.java index 75baedcd05..f560e6912c 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/UriTemplateServletHandlerMethodTests.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/UriTemplateServletHandlerMethodTests.java @@ -51,6 +51,7 @@ import org.springframework.web.servlet.View; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver; import org.springframework.web.servlet.mvc.annotation.UriTemplateServletAnnotationControllerTests; +import org.springframework.web.servlet.mvc.annotation.UriTemplateServletAnnotationControllerTests.VariableNamesController; import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver; import org.springframework.web.servlet.view.AbstractView; @@ -320,6 +321,19 @@ public class UriTemplateServletHandlerMethodTests { assertEquals("bar-bar", response.getContentAsString()); } + /* + * See SPR-8543 + */ + @Test + public void variableNamesWithUrlExtension() throws Exception { + initDispatcherServlet(VariableNamesController.class, null); + + MockHttpServletRequest request = new MockHttpServletRequest("GET", "/test/foo.json"); + MockHttpServletResponse response = new MockHttpServletResponse(); + servlet.service(request, response); + assertEquals("foo-foo", response.getContentAsString()); + } + /* * See SPR-6978 */ diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java index 3cdf876d18..cf2761718f 100644 --- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java +++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java @@ -17,6 +17,7 @@ package org.springframework.web.servlet.resource; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import javax.servlet.http.HttpServletResponse; @@ -137,6 +138,14 @@ public class ResourceHttpRequestHandlerTests { response = new MockHttpServletResponse(); handler.handleRequest(request, response); assertEquals(404, response.getStatus()); + + handler.setLocations(Arrays.asList(new ClassPathResource("testsecret/", getClass()))); + request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "secret.txt"); + response = new MockHttpServletResponse(); + handler.handleRequest(request, response); + assertEquals(200, response.getStatus()); + assertEquals("text/plain", response.getContentType()); + assertEquals("big secret", response.getContentAsString()); } @Test diff --git a/org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/resource/testsecret/secret.txt b/org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/resource/testsecret/secret.txt new file mode 100644 index 0000000000..541425afce --- /dev/null +++ b/org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/resource/testsecret/secret.txt @@ -0,0 +1 @@ +big secret \ No newline at end of file