Browse Source

SPR-8543 Fix issue in AnnotationMethodHandlerAdapter with extracting URI template variable from URL with file extension

pull/7/head
Rossen Stoyanchev 14 years ago
parent
commit
38a6660777
  1. 35
      org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/mvc/annotation/AnnotationMethodHandlerAdapter.java
  2. 13
      org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/annotation/UriTemplateServletAnnotationControllerTests.java
  3. 14
      org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/mvc/method/annotation/UriTemplateServletHandlerMethodTests.java
  4. 9
      org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java
  5. 1
      org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/resource/testsecret/secret.txt

35
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.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; 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.mvc.multiaction.NoSuchRequestHandlingMethodException;
import org.springframework.web.servlet.support.RequestContextUtils; import org.springframework.web.servlet.support.RequestContextUtils;
import org.springframework.web.servlet.support.WebContentGenerator; import org.springframework.web.servlet.support.WebContentGenerator;
import org.springframework.web.util.UriTemplate;
import org.springframework.web.util.UrlPathHelper; import org.springframework.web.util.UrlPathHelper;
import org.springframework.web.util.WebUtils; import org.springframework.web.util.WebUtils;
@ -587,7 +589,7 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
if (!typeLevelPattern.startsWith("/")) { if (!typeLevelPattern.startsWith("/")) {
typeLevelPattern = "/" + typeLevelPattern; typeLevelPattern = "/" + typeLevelPattern;
} }
if (isPathMatchInternal(typeLevelPattern, lookupPath)) { if (getMatchingPattern(typeLevelPattern, lookupPath) != null) {
if (mappingInfo.matches(request)) { if (mappingInfo.matches(request)) {
match = true; match = true;
mappingInfo.addMatchedPattern(typeLevelPattern); mappingInfo.addMatchedPattern(typeLevelPattern);
@ -695,8 +697,9 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
typeLevelPattern = "/" + typeLevelPattern; typeLevelPattern = "/" + typeLevelPattern;
} }
String combinedPattern = pathMatcher.combine(typeLevelPattern, methodLevelPattern); String combinedPattern = pathMatcher.combine(typeLevelPattern, methodLevelPattern);
if (isPathMatchInternal(combinedPattern, lookupPath)) { String matchingPattern = getMatchingPattern(combinedPattern, lookupPath);
return combinedPattern; if (matchingPattern != null) {
return matchingPattern;
} }
} }
return null; return null;
@ -704,30 +707,30 @@ public class AnnotationMethodHandlerAdapter extends WebContentGenerator
String bestMatchingPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); String bestMatchingPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
if (StringUtils.hasText(bestMatchingPattern) && bestMatchingPattern.endsWith("*")) { if (StringUtils.hasText(bestMatchingPattern) && bestMatchingPattern.endsWith("*")) {
String combinedPattern = pathMatcher.combine(bestMatchingPattern, methodLevelPattern); String combinedPattern = pathMatcher.combine(bestMatchingPattern, methodLevelPattern);
if (!combinedPattern.equals(bestMatchingPattern) && String matchingPattern = getMatchingPattern(combinedPattern, lookupPath);
(isPathMatchInternal(combinedPattern, lookupPath))) { if ((matchingPattern != null) && !matchingPattern.equals(bestMatchingPattern)) {
return combinedPattern; return matchingPattern;
} }
} }
if (isPathMatchInternal(methodLevelPattern, lookupPath)) { return getMatchingPattern(methodLevelPattern, lookupPath);
return methodLevelPattern;
}
return null;
} }
private boolean isPathMatchInternal(String pattern, String lookupPath) { private String getMatchingPattern(String pattern, String lookupPath) {
if (pattern.equals(lookupPath) || pathMatcher.match(pattern, lookupPath)) { if (pattern.equals(lookupPath)) {
return true; return pattern;
} }
boolean hasSuffix = pattern.indexOf('.') != -1; boolean hasSuffix = pattern.indexOf('.') != -1;
if (!hasSuffix && pathMatcher.match(pattern + ".*", lookupPath)) { if (!hasSuffix && pathMatcher.match(pattern + ".*", lookupPath)) {
return true; return pattern + ".*";
}
if (pathMatcher.match(pattern, lookupPath)) {
return pattern;
} }
boolean endsWithSlash = pattern.endsWith("/"); boolean endsWithSlash = pattern.endsWith("/");
if (!endsWithSlash && pathMatcher.match(pattern + "/", lookupPath)) { if (!endsWithSlash && pathMatcher.match(pattern + "/", lookupPath)) {
return true; return pattern + "/";
} }
return false; return null;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")

13
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()); 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 * See SPR-6906
*/ */

14
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.ViewResolver;
import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver; import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver;
import org.springframework.web.servlet.mvc.annotation.UriTemplateServletAnnotationControllerTests; 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.mvc.support.DefaultHandlerExceptionResolver;
import org.springframework.web.servlet.view.AbstractView; import org.springframework.web.servlet.view.AbstractView;
@ -320,6 +321,19 @@ public class UriTemplateServletHandlerMethodTests {
assertEquals("bar-bar", response.getContentAsString()); 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 * See SPR-6978
*/ */

9
org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java

@ -17,6 +17,7 @@
package org.springframework.web.servlet.resource; package org.springframework.web.servlet.resource;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
@ -137,6 +138,14 @@ public class ResourceHttpRequestHandlerTests {
response = new MockHttpServletResponse(); response = new MockHttpServletResponse();
handler.handleRequest(request, response); handler.handleRequest(request, response);
assertEquals(404, response.getStatus()); assertEquals(404, response.getStatus());
handler.setLocations(Arrays.<Resource>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 @Test

1
org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/resource/testsecret/secret.txt

@ -0,0 +1 @@
big secret
Loading…
Cancel
Save