SPR-6280 - PathVariable resolution does not work properly

This commit is contained in:
Arjen Poutsma
2009-11-24 13:53:37 +00:00
parent be60908d6d
commit ef50082cad
6 changed files with 102 additions and 8 deletions

View File

@@ -19,6 +19,8 @@ package org.springframework.web.servlet.handler;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -214,13 +216,20 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping {
return buildPathExposingHandler(handler, urlPath, null);
}
// Pattern match?
String bestPathMatch = null;
List<String> matchingPaths = new ArrayList<String>();
for (String registeredPath : this.handlerMap.keySet()) {
if (getPathMatcher().match(registeredPath, urlPath) &&
(bestPathMatch == null || bestPathMatch.length() < registeredPath.length())) {
bestPathMatch = registeredPath;
if (getPathMatcher().match(registeredPath, urlPath)) {
matchingPaths.add(registeredPath);
}
}
String bestPathMatch = null;
if (!matchingPaths.isEmpty()) {
Collections.sort(matchingPaths, getPathMatcher().getPatternComparator(urlPath));
if (logger.isDebugEnabled()) {
logger.debug("Matching path for request [" + urlPath + "] are " + matchingPaths);
}
bestPathMatch = matchingPaths.get(0);
}
if (bestPathMatch != null) {
handler = this.handlerMap.get(bestPathMatch);
// Bean name or resolved handler?

View File

@@ -221,6 +221,22 @@ public class UriTemplateServletAnnotationControllerTests {
}
@Test
public void multiPaths() throws Exception {
initServlet(MultiPathController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/category/page/5");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
assertEquals("handle4-page-5", response.getContentAsString());
request = new MockHttpServletRequest("GET", "/category/page/5.html");
response = new MockHttpServletResponse();
servlet.service(request, response);
assertEquals("handle4-page-5", response.getContentAsString());
}
private void initServlet(final Class<?> controllerclass) throws ServletException {
servlet = new DispatcherServlet() {
@Override
@@ -258,6 +274,17 @@ public class UriTemplateServletAnnotationControllerTests {
assertEquals("test-hotel.with.dot", response.getContentAsString());
}
@Test
public void customRegex() throws Exception {
initServlet(CustomRegexController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/42");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
assertEquals("test-42", response.getContentAsString());
}
/*
* Controllers
*/
@@ -371,12 +398,24 @@ public class UriTemplateServletAnnotationControllerTests {
@RequestMapping("hotels")
public static class ImplicitSubPathController {
@RequestMapping("{hotel}")
@RequestMapping("{hotel:.*}")
public void handleHotel(@PathVariable String hotel, Writer writer) throws IOException {
writer.write("test-" + hotel);
}
}
@Controller
public static class CustomRegexController {
@RequestMapping("/{root:\\d+}")
public void handle(@PathVariable("root") int root, Writer writer) throws IOException {
assertEquals("Invalid path variable value", 42, root);
writer.write("test-" + root);
}
}
@Controller
@RequestMapping("hotels")
public static class CrudController {
@@ -429,4 +468,34 @@ public class UriTemplateServletAnnotationControllerTests {
}
}
@Controller
@RequestMapping("/category")
public static class MultiPathController {
@RequestMapping(value = {"/{category}/page/{page}", "/**/{category}/page/{page}"})
public void category(@PathVariable String category, @PathVariable int page, Writer writer) throws IOException {
writer.write("handle1-");
writer.write("category-" + category);
writer.write("page-" + page);
}
@RequestMapping(value = {"/{category}", "/**/{category}"})
public void category(@PathVariable String category, Writer writer) throws IOException {
writer.write("handle2-");
writer.write("category-" + category);
}
@RequestMapping(value = {""})
public void category(Writer writer) throws IOException {
writer.write("handle3");
}
@RequestMapping(value = {"/page/{page}"})
public void category(@PathVariable int page, Writer writer) throws IOException {
writer.write("handle4-");
writer.write("page-" + page);
}
}
}