SPR-5367: PathVariable mappings are greedy over hard coded mappings

This commit is contained in:
Arjen Poutsma
2009-01-21 17:45:42 +00:00
parent 5d5e41269b
commit c7d1d3ccb8
4 changed files with 217 additions and 55 deletions

View File

@@ -0,0 +1,94 @@
/*
* Copyright 2002-2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.mvc.annotation;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import static org.junit.Assert.assertEquals;
import org.junit.Before;
import org.junit.Test;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* @author Arjen Poutsma
*/
public class RequestMappingInfoComparatorTest {
private AnnotationMethodHandlerAdapter.RequestMappingInfoComparator comparator;
private AnnotationMethodHandlerAdapter.RequestMappingInfo emptyInfo;
private AnnotationMethodHandlerAdapter.RequestMappingInfo oneMethodInfo;
private AnnotationMethodHandlerAdapter.RequestMappingInfo twoMethodsInfo;
private AnnotationMethodHandlerAdapter.RequestMappingInfo oneMethodOneParamInfo;
private AnnotationMethodHandlerAdapter.RequestMappingInfo oneMethodTwoParamsInfo;
@Before
public void setUp() throws NoSuchMethodException {
comparator = new AnnotationMethodHandlerAdapter.RequestMappingInfoComparator(new MockComparator());
emptyInfo = new AnnotationMethodHandlerAdapter.RequestMappingInfo();
oneMethodInfo = new AnnotationMethodHandlerAdapter.RequestMappingInfo();
oneMethodInfo.methods = new RequestMethod[]{RequestMethod.GET};
twoMethodsInfo = new AnnotationMethodHandlerAdapter.RequestMappingInfo();
twoMethodsInfo.methods = new RequestMethod[]{RequestMethod.GET, RequestMethod.POST};
oneMethodOneParamInfo = new AnnotationMethodHandlerAdapter.RequestMappingInfo();
oneMethodOneParamInfo.methods = new RequestMethod[]{RequestMethod.GET};
oneMethodOneParamInfo.params = new String[]{"param"};
oneMethodTwoParamsInfo = new AnnotationMethodHandlerAdapter.RequestMappingInfo();
oneMethodTwoParamsInfo.methods = new RequestMethod[]{RequestMethod.GET};
oneMethodTwoParamsInfo.params = new String[]{"param1", "param2"};
}
@Test
public void sort() {
List<AnnotationMethodHandlerAdapter.RequestMappingInfo> infos = new ArrayList<AnnotationMethodHandlerAdapter.RequestMappingInfo>();
infos.add(emptyInfo);
infos.add(oneMethodInfo);
infos.add(twoMethodsInfo);
infos.add(oneMethodOneParamInfo);
infos.add(oneMethodTwoParamsInfo);
Collections.shuffle(infos);
Collections.sort(infos, comparator);
assertEquals(oneMethodTwoParamsInfo, infos.get(0));
assertEquals(oneMethodOneParamInfo, infos.get(1));
assertEquals(oneMethodInfo, infos.get(2));
assertEquals(twoMethodsInfo, infos.get(3));
assertEquals(emptyInfo, infos.get(4));
}
private static class MockComparator implements Comparator<String> {
public int compare(String s1, String s2) {
return 0;
}
}
}

View File

@@ -30,6 +30,7 @@ import java.util.Map;
import java.util.Set;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -801,6 +802,24 @@ public class ServletAnnotationControllerTests {
}
}
@Test
public void pathOrdering() throws ServletException, IOException {
@SuppressWarnings("serial") DispatcherServlet servlet = new DispatcherServlet() {
@Override
protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) {
GenericWebApplicationContext wac = new GenericWebApplicationContext();
wac.registerBeanDefinition("controller", new RootBeanDefinition(PathOrderingController.class));
wac.refresh();
return wac;
}
};
servlet.init(new MockServletConfig());
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/dir/myPath1.do");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
assertEquals("method1", response.getContentAsString());
}
/*
* Controllers
@@ -1350,4 +1369,19 @@ public class ServletAnnotationControllerTests {
}
}
@Controller
public static class PathOrderingController {
@RequestMapping(value = {"/dir/myPath1.do", "/**/*.do"})
public void method1(Writer writer) throws IOException {
writer.write("method1");
}
@RequestMapping("/dir/*.do")
public void method2(Writer writer) throws IOException {
writer.write("method2");
}
}
}

View File

@@ -65,7 +65,7 @@ public class UriTemplateServletAnnotationControllerTests {
public void ambiguous() throws Exception {
initServlet(AmbiguousUriTemplateController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels/12345");
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels/new");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
assertEquals("specific", response.getContentAsString());
@@ -162,16 +162,25 @@ public class UriTemplateServletAnnotationControllerTests {
@Controller
public static class AmbiguousUriTemplateController {
@RequestMapping("/hotels/{hotel}")
public void handleVars(Writer writer) throws IOException {
writer.write("variables");
}
@RequestMapping("/hotels/12345")
@RequestMapping("/hotels/new")
public void handleSpecific(Writer writer) throws IOException {
writer.write("specific");
}
/*
@RequestMapping("/hotels/{hotel}")
public void handleVars(@PathVariable("hotel") String hotel, Writer writer) throws IOException {
assertEquals("Invalid path variable value", "42", hotel);
writer.write("variables");
}
*/
@RequestMapping("/hotels/*")
public void handleWildCard(Writer writer) throws IOException {
writer.write("wildcard");
}
}
}