SPR-8215 Move HandlerMethod code into trunk
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.handler;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Comparator;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.util.PathMatcher;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.util.UrlPathHelper;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Test for {@link AbstractHandlerMethodMapping}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class HandlerMethodMappingTests {
|
||||
|
||||
private AbstractHandlerMethodMapping<String> mapping;
|
||||
|
||||
private HandlerMethod handlerMethod1;
|
||||
|
||||
private HandlerMethod handlerMethod2;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mapping = new MyHandlerMethodMapping();
|
||||
MyHandler handler = new MyHandler();
|
||||
handlerMethod1 = new HandlerMethod(handler, "handlerMethod1");
|
||||
handlerMethod2 = new HandlerMethod(handler, "handlerMethod2");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void registerDuplicates() {
|
||||
mapping.registerHandlerMethod("foo", handlerMethod1);
|
||||
mapping.registerHandlerMethod("foo", handlerMethod2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void directMatch() throws Exception {
|
||||
String key = "foo";
|
||||
mapping.registerHandlerMethod(key, handlerMethod1);
|
||||
|
||||
HandlerMethod result = mapping.getHandlerInternal(new MockHttpServletRequest("GET", key));
|
||||
assertEquals(handlerMethod1, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void patternMatch() throws Exception {
|
||||
mapping.registerHandlerMethod("/fo*", handlerMethod1);
|
||||
mapping.registerHandlerMethod("/f*", handlerMethod1);
|
||||
|
||||
HandlerMethod result = mapping.getHandlerInternal(new MockHttpServletRequest("GET", "/foo"));
|
||||
assertEquals(handlerMethod1, result);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void ambiguousMatch() throws Exception {
|
||||
mapping.registerHandlerMethod("/f?o", handlerMethod1);
|
||||
mapping.registerHandlerMethod("/fo?", handlerMethod2);
|
||||
|
||||
mapping.getHandlerInternal(new MockHttpServletRequest("GET", "/foo"));
|
||||
}
|
||||
|
||||
private static class MyHandlerMethodMapping extends AbstractHandlerMethodMapping<String> {
|
||||
|
||||
private UrlPathHelper urlPathHelper = new UrlPathHelper();
|
||||
|
||||
private PathMatcher pathMatcher = new AntPathMatcher();
|
||||
|
||||
@Override
|
||||
protected String getKeyForRequest(HttpServletRequest request) throws Exception {
|
||||
return urlPathHelper.getLookupPathForRequest(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getMatchingKey(String pattern, HttpServletRequest request) {
|
||||
String lookupPath = urlPathHelper.getLookupPathForRequest(request);
|
||||
|
||||
return pathMatcher.match(pattern, lookupPath) ? pattern : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getKeyForMethod(Method method) {
|
||||
String methodName = method.getName();
|
||||
return methodName.startsWith("handler") ? methodName : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Comparator<String> getKeyComparator(HttpServletRequest request) {
|
||||
String lookupPath = urlPathHelper.getLookupPathForRequest(request);
|
||||
|
||||
return pathMatcher.getPatternComparator(lookupPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isHandler(String beanName) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyHandler {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void handlerMethod1() {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void handlerMethod2() {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.method.annotation;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
|
||||
import org.springframework.aop.interceptor.SimpleTraceInterceptor;
|
||||
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.ReflectionUtils.MethodFilter;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.support.DefaultDataBinderFactory;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.context.support.GenericWebApplicationContext;
|
||||
import org.springframework.web.method.HandlerMethodSelector;
|
||||
import org.springframework.web.method.annotation.support.ModelAttributeMethodProcessor;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolverContainer;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandlerContainer;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.support.DefaultMethodReturnValueHandler;
|
||||
|
||||
/**
|
||||
* Test various scenarios for detecting method-level and method parameter annotations depending
|
||||
* on where they are located -- on interfaces, parent classes, in parameterized methods, or in
|
||||
* combination with proxies.
|
||||
*
|
||||
* Note the following:
|
||||
* <ul>
|
||||
* <li>Parameterized methods cannot be used in combination with JDK dynamic proxies since the
|
||||
* proxy interface does not contain the bridged methods that need to be invoked.
|
||||
* <li>When using JDK dynamic proxies, the proxied interface must contain all required method
|
||||
* and method parameter annotations.
|
||||
* <li>Method-level annotations can be placed on super types (interface or parent class) while
|
||||
* method parameter annotations must be present on the method being invoked.
|
||||
* </ul>
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class ControllerMethodAnnotationDetectionTests {
|
||||
|
||||
@Parameters
|
||||
public static Collection<Object[]> handlerTypes() {
|
||||
return Arrays.asList(new Object[][] {
|
||||
{ new MappingIfcController(), false },
|
||||
{ new MappingAbstractClassController(), false },
|
||||
{ new ParameterizedIfcController(), false },
|
||||
{ new MappingParameterizedIfcController(), false },
|
||||
{ new MappingIfcProxyController(), true },
|
||||
{ new PlainController(), true },
|
||||
{ new MappingAbstractClassController(), true }
|
||||
});
|
||||
}
|
||||
|
||||
private Object handler;
|
||||
|
||||
private boolean useAutoProxy;
|
||||
|
||||
public ControllerMethodAnnotationDetectionTests(Object handler, boolean useAutoProxy) {
|
||||
this.handler = handler;
|
||||
this.useAutoProxy = useAutoProxy;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void invokeModelAttributeMethod() throws Exception {
|
||||
ServletInvocableHandlerMethod requestMappingMethod = createRequestMappingMethod(handler, useAutoProxy);
|
||||
|
||||
ModelAttribute annot = requestMappingMethod.getMethodAnnotation(ModelAttribute.class);
|
||||
assertEquals("Failed to detect method annotation", "attrName", annot.value());
|
||||
|
||||
MockHttpServletRequest servletRequest = new MockHttpServletRequest();
|
||||
NativeWebRequest webRequest = new ServletWebRequest(servletRequest, new MockHttpServletResponse());
|
||||
servletRequest.setParameter("name", "Chad");
|
||||
|
||||
ModelMap model = new ExtendedModelMap();
|
||||
ModelAndView mav = requestMappingMethod.invokeAndHandle(webRequest, model);
|
||||
|
||||
Object modelAttr = mav.getModelMap().get("attrName");
|
||||
|
||||
assertEquals(TestBean.class, modelAttr.getClass());
|
||||
assertEquals("Chad", ((TestBean) modelAttr).getName());
|
||||
}
|
||||
|
||||
private ServletInvocableHandlerMethod createRequestMappingMethod(Object handler, boolean useAutoProxy) {
|
||||
if (useAutoProxy) {
|
||||
handler = getProxyBean(handler);
|
||||
}
|
||||
HandlerMethodArgumentResolverContainer argResolvers = new HandlerMethodArgumentResolverContainer();
|
||||
argResolvers.registerArgumentResolver(new ModelAttributeMethodProcessor(false));
|
||||
|
||||
HandlerMethodReturnValueHandlerContainer handlers = new HandlerMethodReturnValueHandlerContainer();
|
||||
handlers.registerReturnValueHandler(new ModelAttributeMethodProcessor(false));
|
||||
handlers.registerReturnValueHandler(new DefaultMethodReturnValueHandler(null));
|
||||
|
||||
Class<?> handlerType = ClassUtils.getUserClass(handler.getClass());
|
||||
Set<Method> methods = HandlerMethodSelector.selectMethods(handlerType, REQUEST_MAPPING_METHODS);
|
||||
Method method = methods.iterator().next();
|
||||
|
||||
ServletInvocableHandlerMethod attrMethod = new ServletInvocableHandlerMethod(handler, method);
|
||||
attrMethod.setArgumentResolverContainer(argResolvers);
|
||||
attrMethod.setReturnValueHandlers(handlers);
|
||||
attrMethod.setDataBinderFactory(new DefaultDataBinderFactory(null));
|
||||
|
||||
return attrMethod;
|
||||
}
|
||||
|
||||
private Object getProxyBean(Object handler) {
|
||||
GenericWebApplicationContext wac = new GenericWebApplicationContext();
|
||||
wac.registerBeanDefinition("controller", new RootBeanDefinition(handler.getClass()));
|
||||
|
||||
DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
|
||||
autoProxyCreator.setBeanFactory(wac.getBeanFactory());
|
||||
wac.getBeanFactory().addBeanPostProcessor(autoProxyCreator);
|
||||
wac.getBeanFactory().registerSingleton("advsr", new DefaultPointcutAdvisor(new SimpleTraceInterceptor()));
|
||||
|
||||
wac.refresh();
|
||||
|
||||
return wac.getBean("controller");
|
||||
}
|
||||
|
||||
public static MethodFilter REQUEST_MAPPING_METHODS = new MethodFilter() {
|
||||
|
||||
public boolean matches(Method method) {
|
||||
return AnnotationUtils.findAnnotation(method, RequestMapping.class) != null;
|
||||
}
|
||||
};
|
||||
|
||||
private interface MappingIfc {
|
||||
@RequestMapping
|
||||
@ModelAttribute("attrName")
|
||||
TestBean model(TestBean input);
|
||||
}
|
||||
|
||||
private static class MappingIfcController implements MappingIfc {
|
||||
public TestBean model(@ModelAttribute TestBean input) {
|
||||
return new TestBean(input.getName());
|
||||
}
|
||||
}
|
||||
|
||||
private interface MappingProxyIfc {
|
||||
@RequestMapping
|
||||
@ModelAttribute("attrName")
|
||||
TestBean model(@ModelAttribute TestBean input);
|
||||
}
|
||||
|
||||
private static class MappingIfcProxyController implements MappingProxyIfc {
|
||||
@ModelAttribute("attrName")
|
||||
public TestBean model(@ModelAttribute TestBean input) {
|
||||
return new TestBean(input.getName());
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class MappingAbstractClass {
|
||||
@RequestMapping
|
||||
@ModelAttribute("attrName")
|
||||
TestBean model(TestBean input) {
|
||||
return new TestBean(input.getName());
|
||||
}
|
||||
}
|
||||
|
||||
public static class MappingAbstractClassController extends MappingAbstractClass {
|
||||
public TestBean model(@ModelAttribute TestBean input) {
|
||||
TestBean testBean = super.model(input);
|
||||
testBean.setAge(14);
|
||||
return testBean;
|
||||
}
|
||||
}
|
||||
|
||||
public interface ParameterizedIfc<TB, S> {
|
||||
TB model(S input);
|
||||
}
|
||||
|
||||
public static class ParameterizedIfcController implements ParameterizedIfc<TestBean, TestBean> {
|
||||
@RequestMapping
|
||||
@ModelAttribute("attrName")
|
||||
public TestBean model(@ModelAttribute TestBean input) {
|
||||
return new TestBean(input.getName());
|
||||
}
|
||||
}
|
||||
|
||||
public interface MappingParameterizedIfc<TB, S> {
|
||||
@RequestMapping
|
||||
@ModelAttribute("attrName")
|
||||
TB model(S input);
|
||||
}
|
||||
|
||||
public static class MappingParameterizedIfcController implements MappingParameterizedIfc<TestBean, TestBean> {
|
||||
public TestBean model(@ModelAttribute TestBean input) {
|
||||
return new TestBean(input.getName());
|
||||
}
|
||||
}
|
||||
|
||||
public interface MappingParameterizedProxyIfc<TB, S> {
|
||||
@RequestMapping
|
||||
@ModelAttribute("attrName")
|
||||
TB model(@ModelAttribute("inputName") S input);
|
||||
}
|
||||
|
||||
public static class MappingParameterizedProxyIfcController implements MappingParameterizedProxyIfc<TestBean, TestBean> {
|
||||
@RequestMapping
|
||||
@ModelAttribute("attrName")
|
||||
public TestBean model(@ModelAttribute TestBean input) {
|
||||
return new TestBean(input.getName());
|
||||
}
|
||||
}
|
||||
|
||||
public static class PlainController {
|
||||
public PlainController() {
|
||||
}
|
||||
|
||||
@RequestMapping
|
||||
@ModelAttribute("attrName")
|
||||
public TestBean model(@ModelAttribute TestBean input) {
|
||||
return new TestBean(input.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.method.annotation;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestCondition;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestConditionFactory;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class RequestConditionFactoryTests {
|
||||
|
||||
@Test
|
||||
public void paramEquals() {
|
||||
assertEquals(getSingleParamCondition("foo"), getSingleParamCondition("foo"));
|
||||
assertFalse(getSingleParamCondition("foo").equals(getSingleParamCondition("bar")));
|
||||
assertFalse(getSingleParamCondition("foo").equals(getSingleParamCondition("FOO")));
|
||||
assertEquals(getSingleParamCondition("foo=bar"), getSingleParamCondition("foo=bar"));
|
||||
assertFalse(getSingleParamCondition("foo=bar").equals(getSingleParamCondition("FOO=bar")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerEquals() {
|
||||
assertEquals(getSingleHeaderCondition("foo"), getSingleHeaderCondition("foo"));
|
||||
assertEquals(getSingleHeaderCondition("foo"), getSingleHeaderCondition("FOO"));
|
||||
assertFalse(getSingleHeaderCondition("foo").equals(getSingleHeaderCondition("bar")));
|
||||
assertEquals(getSingleHeaderCondition("foo=bar"), getSingleHeaderCondition("foo=bar"));
|
||||
assertEquals(getSingleHeaderCondition("foo=bar"), getSingleHeaderCondition("FOO=bar"));
|
||||
assertEquals(getSingleHeaderCondition("content-type=text/xml"),
|
||||
getSingleHeaderCondition("Content-Type=TEXT/XML"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerPresent() {
|
||||
RequestCondition condition = getSingleHeaderCondition("accept");
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addHeader("Accept", "");
|
||||
|
||||
assertTrue(condition.match(request));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerPresentNoMatch() {
|
||||
RequestCondition condition = getSingleHeaderCondition("foo");
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addHeader("bar", "");
|
||||
|
||||
assertFalse(condition.match(request));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerNotPresent() {
|
||||
RequestCondition condition = getSingleHeaderCondition("!accept");
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
|
||||
assertTrue(condition.match(request));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerValueMatch() {
|
||||
RequestCondition condition = getSingleHeaderCondition("foo=bar");
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addHeader("foo", "bar");
|
||||
|
||||
assertTrue(condition.match(request));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerValueNoMatch() {
|
||||
RequestCondition condition = getSingleHeaderCondition("foo=bar");
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addHeader("foo", "bazz");
|
||||
|
||||
assertFalse(condition.match(request));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerCaseSensitiveValueMatch() {
|
||||
RequestCondition condition = getSingleHeaderCondition("foo=Bar");
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addHeader("foo", "bar");
|
||||
|
||||
assertFalse(condition.match(request));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void headerValueMatchNegated() {
|
||||
RequestCondition condition = getSingleHeaderCondition("foo!=bar");
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addHeader("foo", "baz");
|
||||
|
||||
assertTrue(condition.match(request));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mediaTypeHeaderValueMatch() {
|
||||
RequestCondition condition = getSingleHeaderCondition("accept=text/html");
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addHeader("Accept", "text/html");
|
||||
|
||||
assertTrue(condition.match(request));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mediaTypeHeaderValueMatchNegated() {
|
||||
RequestCondition condition = getSingleHeaderCondition("accept!=text/html");
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||
request.addHeader("Accept", "application/html");
|
||||
|
||||
assertTrue(condition.match(request));
|
||||
}
|
||||
|
||||
private RequestCondition getSingleHeaderCondition(String expression) {
|
||||
Set<RequestCondition> conditions = RequestConditionFactory.parseHeaders(expression);
|
||||
assertEquals(1, conditions.size());
|
||||
return conditions.iterator().next();
|
||||
}
|
||||
|
||||
private RequestCondition getSingleParamCondition(String expression) {
|
||||
Set<RequestCondition> conditions = RequestConditionFactory.parseParams(expression);
|
||||
assertEquals(1, conditions.size());
|
||||
return conditions.iterator().next();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.method.annotation;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestConditionFactory;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestKey;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodMapping;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class RequestKeyComparatorTests {
|
||||
|
||||
private RequestMappingHandlerMethodMapping handlerMapping;
|
||||
|
||||
private MockHttpServletRequest request;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.handlerMapping = new RequestMappingHandlerMethodMapping();
|
||||
this.request = new MockHttpServletRequest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void moreSpecificPatternWins() {
|
||||
request.setRequestURI("/foo");
|
||||
Comparator<RequestKey> comparator = handlerMapping.getKeyComparator(request);
|
||||
RequestKey key1 = new RequestKey(asList("/fo*"), null, null, null);
|
||||
RequestKey key2 = new RequestKey(asList("/foo"), null, null, null);
|
||||
|
||||
assertEquals(1, comparator.compare(key1, key2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equalPatterns() {
|
||||
request.setRequestURI("/foo");
|
||||
Comparator<RequestKey> comparator = handlerMapping.getKeyComparator(request);
|
||||
RequestKey key1 = new RequestKey(asList("/foo*"), null, null, null);
|
||||
RequestKey key2 = new RequestKey(asList("/foo*"), null, null, null);
|
||||
|
||||
assertEquals(0, comparator.compare(key1, key2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void greaterNumberOfMatchingPatternsWins() throws Exception {
|
||||
request.setRequestURI("/foo.html");
|
||||
RequestKey key1 = new RequestKey(asList("/foo", "*.jpeg"), null, null, null);
|
||||
RequestKey key2 = new RequestKey(asList("/foo", "*.html"), null, null, null);
|
||||
RequestKey match1 = handlerMapping.getMatchingKey(key1, request);
|
||||
RequestKey match2 = handlerMapping.getMatchingKey(key2, request);
|
||||
List<RequestKey> matches = asList(match1, match2);
|
||||
Collections.sort(matches, handlerMapping.getKeyComparator(request));
|
||||
|
||||
assertSame(match2.getPatterns(), matches.get(0).getPatterns());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void oneMethodWinsOverNone() {
|
||||
Comparator<RequestKey> comparator = handlerMapping.getKeyComparator(request);
|
||||
RequestKey key1 = new RequestKey(null, null, null, null);
|
||||
RequestKey key2 = new RequestKey(null, asList(RequestMethod.GET), null, null);
|
||||
|
||||
assertEquals(1, comparator.compare(key1, key2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodsAndParams() {
|
||||
RequestKey empty = new RequestKey(null, null, null, null);
|
||||
RequestKey oneMethod = new RequestKey(null, asList(RequestMethod.GET), null, null);
|
||||
RequestKey oneMethodOneParam =
|
||||
new RequestKey(null, asList(RequestMethod.GET), RequestConditionFactory.parseParams("foo"), null);
|
||||
List<RequestKey> list = asList(empty, oneMethod, oneMethodOneParam);
|
||||
Collections.shuffle(list);
|
||||
Collections.sort(list, handlerMapping.getKeyComparator(request));
|
||||
|
||||
assertEquals(oneMethodOneParam, list.get(0));
|
||||
assertEquals(oneMethod, list.get(1));
|
||||
assertEquals(empty, list.get(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore // TODO : remove ignore
|
||||
public void acceptHeaders() {
|
||||
RequestKey html = new RequestKey(null, null, null, RequestConditionFactory.parseHeaders("accept=text/html"));
|
||||
RequestKey xml = new RequestKey(null, null, null, RequestConditionFactory.parseHeaders("accept=application/xml"));
|
||||
RequestKey none = new RequestKey(null, null, null, null);
|
||||
|
||||
request.addHeader("Accept", "application/xml, text/html");
|
||||
Comparator<RequestKey> comparator = handlerMapping.getKeyComparator(request);
|
||||
|
||||
assertTrue(comparator.compare(html, xml) > 0);
|
||||
assertTrue(comparator.compare(xml, html) < 0);
|
||||
assertTrue(comparator.compare(xml, none) < 0);
|
||||
assertTrue(comparator.compare(none, xml) > 0);
|
||||
assertTrue(comparator.compare(html, none) < 0);
|
||||
assertTrue(comparator.compare(none, html) > 0);
|
||||
|
||||
request = new MockHttpServletRequest();
|
||||
request.addHeader("Accept", "application/xml, text/*");
|
||||
comparator = handlerMapping.getKeyComparator(request);
|
||||
|
||||
assertTrue(comparator.compare(html, xml) > 0);
|
||||
assertTrue(comparator.compare(xml, html) < 0);
|
||||
|
||||
request = new MockHttpServletRequest();
|
||||
request.addHeader("Accept", "application/pdf");
|
||||
comparator = handlerMapping.getKeyComparator(request);
|
||||
|
||||
assertTrue(comparator.compare(html, xml) == 0);
|
||||
assertTrue(comparator.compare(xml, html) == 0);
|
||||
|
||||
// See SPR-7000
|
||||
request = new MockHttpServletRequest();
|
||||
request.addHeader("Accept", "text/html;q=0.9,application/xml");
|
||||
comparator = handlerMapping.getKeyComparator(request);
|
||||
|
||||
assertTrue(comparator.compare(html, xml) > 0);
|
||||
assertTrue(comparator.compare(xml, html) < 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.method.annotation;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.springframework.web.bind.annotation.RequestMethod.GET;
|
||||
import static org.springframework.web.bind.annotation.RequestMethod.POST;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.util.PathMatcher;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestConditionFactory;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestKey;
|
||||
import org.springframework.web.util.UrlPathHelper;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class RequestKeyTests {
|
||||
|
||||
@Test
|
||||
public void equals() {
|
||||
RequestKey key1 = new RequestKey(asList("/foo"), asList(GET), null, null);
|
||||
RequestKey key2 = new RequestKey(asList("/foo"), asList(GET), null, null);
|
||||
|
||||
assertEquals(key1, key2);
|
||||
assertEquals(key1.hashCode(), key2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equalsPrependSlash() {
|
||||
RequestKey key1 = new RequestKey(asList("/foo"), asList(GET), null, null);
|
||||
RequestKey key2 = new RequestKey(asList("foo"), asList(GET), null, null);
|
||||
|
||||
assertEquals(key1, key2);
|
||||
assertEquals(key1.hashCode(), key2.hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void combinePatterns() {
|
||||
AntPathMatcher pathMatcher = new AntPathMatcher();
|
||||
|
||||
RequestKey key1 = createKeyFromPatterns("/t1", "/t2");
|
||||
RequestKey key2 = createKeyFromPatterns("/m1", "/m2");
|
||||
RequestKey key3 = createKeyFromPatterns("/t1/m1", "/t1/m2", "/t2/m1", "/t2/m2");
|
||||
assertEquals(key3, key1.combine(key2, pathMatcher));
|
||||
|
||||
key1 = createKeyFromPatterns("/t1");
|
||||
key2 = createKeyFromPatterns(new String[] {});
|
||||
key3 = createKeyFromPatterns("/t1");
|
||||
assertEquals(key3, key1.combine(key2, pathMatcher));
|
||||
|
||||
key1 = createKeyFromPatterns(new String[] {});
|
||||
key2 = createKeyFromPatterns("/m1");
|
||||
key3 = createKeyFromPatterns("/m1");
|
||||
assertEquals(key3, key1.combine(key2, pathMatcher));
|
||||
|
||||
key1 = createKeyFromPatterns(new String[] {});
|
||||
key2 = createKeyFromPatterns(new String[] {});
|
||||
key3 = createKeyFromPatterns("/");
|
||||
assertEquals(key3, key1.combine(key2, pathMatcher));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchPatternsToRequest() {
|
||||
UrlPathHelper urlPathHelper = new UrlPathHelper();
|
||||
PathMatcher pathMatcher = new AntPathMatcher();
|
||||
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
|
||||
RequestKey key = new RequestKey(asList("/foo"), null, null, null);
|
||||
RequestKey match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||
|
||||
assertNotNull(match);
|
||||
|
||||
request = new MockHttpServletRequest("GET", "/foo/bar");
|
||||
key = new RequestKey(asList("/foo/*"), null, null, null);
|
||||
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||
|
||||
assertNotNull("Pattern match", match);
|
||||
|
||||
request = new MockHttpServletRequest("GET", "/foo.html");
|
||||
key = new RequestKey(asList("/foo"), null, null, null);
|
||||
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||
|
||||
assertNotNull("Implicit match by extension", match);
|
||||
assertEquals("Contains matched pattern", "/foo.*", match.getPatterns().iterator().next());
|
||||
|
||||
request = new MockHttpServletRequest("GET", "/foo/");
|
||||
key = new RequestKey(asList("/foo"), null, null, null);
|
||||
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||
|
||||
assertNotNull("Implicit match by trailing slash", match);
|
||||
assertEquals("Contains matched pattern", "/foo/", match.getPatterns().iterator().next());
|
||||
|
||||
request = new MockHttpServletRequest("GET", "/foo.html");
|
||||
key = new RequestKey(asList("/foo.jpg"), null, null, null);
|
||||
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||
|
||||
assertNull("Implicit match ignored if pattern has extension", match);
|
||||
|
||||
request = new MockHttpServletRequest("GET", "/foo.html");
|
||||
key = new RequestKey(asList("/foo.jpg"), null, null, null);
|
||||
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||
|
||||
assertNull("Implicit match ignored on pattern with trailing slash", match);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchRequestMethods() {
|
||||
UrlPathHelper urlPathHelper = new UrlPathHelper();
|
||||
PathMatcher pathMatcher = new AntPathMatcher();
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
|
||||
|
||||
RequestKey key = new RequestKey(asList("/foo"), null, null, null);
|
||||
RequestKey match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||
|
||||
assertNotNull("No method matches any method", match);
|
||||
|
||||
key = new RequestKey(asList("/foo"), asList(GET), null, null);
|
||||
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||
|
||||
assertNotNull("Exact match", match);
|
||||
|
||||
key = new RequestKey(asList("/foo"), asList(POST), null, null);
|
||||
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||
|
||||
assertNull("No match", match);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMatchingKeyContent() {
|
||||
UrlPathHelper urlPathHelper = new UrlPathHelper();
|
||||
PathMatcher pathMatcher = new AntPathMatcher();
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
|
||||
|
||||
RequestKey key = new RequestKey(asList("/foo*", "/bar"), asList(GET, POST), null, null);
|
||||
RequestKey match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||
RequestKey expected = new RequestKey(asList("/foo*"), asList(GET), null, null);
|
||||
|
||||
assertEquals("Matching RequestKey contains matched patterns and methods only", expected, match);
|
||||
|
||||
key = new RequestKey(asList("/**", "/foo*", "/foo"), null, null, null);
|
||||
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||
expected = new RequestKey(asList("/foo", "/foo*", "/**"), null, null, null);
|
||||
|
||||
assertEquals("Matched patterns are sorted with best match at the top", expected, match);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParamConditions() {
|
||||
UrlPathHelper urlPathHelper = new UrlPathHelper();
|
||||
PathMatcher pathMatcher = new AntPathMatcher();
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
|
||||
request.setParameter("foo", "bar");
|
||||
|
||||
RequestKey key = new RequestKey(asList("/foo"), null, RequestConditionFactory.parseParams("foo=bar"), null);
|
||||
RequestKey match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||
|
||||
assertNotNull(match);
|
||||
|
||||
key = new RequestKey(asList("/foo"), null, RequestConditionFactory.parseParams("foo!=bar"), null);
|
||||
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||
|
||||
assertNull(match);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testHeaderConditions() {
|
||||
UrlPathHelper urlPathHelper = new UrlPathHelper();
|
||||
PathMatcher pathMatcher = new AntPathMatcher();
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
|
||||
request.addHeader("foo", "bar");
|
||||
|
||||
RequestKey key = new RequestKey(asList("/foo"), null, null, RequestConditionFactory.parseHeaders("foo=bar"));
|
||||
RequestKey match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||
|
||||
assertNotNull(match);
|
||||
|
||||
key = new RequestKey(asList("/foo"), null, null, RequestConditionFactory.parseHeaders("foo!=bar"));
|
||||
match = key.getMatchingKey(request, pathMatcher, urlPathHelper);
|
||||
|
||||
assertNull(match);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateFromServletRequest() {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
|
||||
RequestKey key = RequestKey.createFromServletRequest(request, new UrlPathHelper());
|
||||
assertEquals(new RequestKey(asList("/foo"), asList(RequestMethod.GET), null, null), key);
|
||||
}
|
||||
|
||||
private RequestKey createKeyFromPatterns(String... patterns) {
|
||||
return new RequestKey(asList(patterns), null, null, null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.method.annotation;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.Principal;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.Valid;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.propertyeditors.CustomDateEditor;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.ui.ModelMap;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.annotation.CookieValue;
|
||||
import org.springframework.web.bind.annotation.InitBinder;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.bind.annotation.SessionAttributes;
|
||||
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
|
||||
import org.springframework.web.bind.support.WebArgumentResolver;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.RequestContextHolder;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.context.support.GenericWebApplicationContext;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.method.support.InvocableHandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||
|
||||
/**
|
||||
* A test fixture for higher-level {@link RequestMappingHandlerAdapter} tests.
|
||||
*
|
||||
* <p>The aim here is not to test {@link RequestMappingHandlerAdapter} itself nor to exercise
|
||||
* every {@link Controller @Controller} method feature but to have a place to try any feature
|
||||
* related to {@link Controller @Controller} invocations. Preferably actual tests should be
|
||||
* added to the components that provide that respective functionality.
|
||||
*
|
||||
* <p>The following integration tests for detecting annotations on super types, parameterized
|
||||
* methods, and proxies may also be of interest:
|
||||
* <ul>
|
||||
* <li>{@link RequestMappingHandlerMethodDetectionTests}
|
||||
* <li>{@link ControllerMethodAnnotationDetectionTests}
|
||||
* </ul>
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class RequestMappingHandlerAdapterIntegrationTests {
|
||||
|
||||
private RequestMappingHandlerAdapter handlerAdapter;
|
||||
|
||||
private MockHttpServletRequest request;
|
||||
|
||||
private MockHttpServletResponse response;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
ConfigurableWebBindingInitializer bindingInitializer = new ConfigurableWebBindingInitializer();
|
||||
bindingInitializer.setValidator(new StubValidator());
|
||||
|
||||
this.handlerAdapter = new RequestMappingHandlerAdapter();
|
||||
this.handlerAdapter.setWebBindingInitializer(bindingInitializer);
|
||||
this.handlerAdapter.setCustomArgumentResolvers(new WebArgumentResolver[] { new ColorArgumentResolver() });
|
||||
|
||||
GenericWebApplicationContext context = new GenericWebApplicationContext();
|
||||
context.refresh();
|
||||
|
||||
this.handlerAdapter.setApplicationContext(context);
|
||||
this.handlerAdapter.setBeanFactory(context.getBeanFactory());
|
||||
this.handlerAdapter.afterPropertiesSet();
|
||||
|
||||
this.request = new MockHttpServletRequest();
|
||||
this.response = new MockHttpServletResponse();
|
||||
|
||||
// Expose request to the current thread (for SpEL expressions)
|
||||
RequestContextHolder.setRequestAttributes(new ServletWebRequest(request));
|
||||
}
|
||||
|
||||
@After
|
||||
public void teardown() {
|
||||
RequestContextHolder.resetRequestAttributes();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleMvc() throws Exception {
|
||||
Class<?>[] paramTypes = new Class<?>[] { int.class, String.class, String.class, String.class, Map.class,
|
||||
Date.class, Map.class, String.class, String.class, TestBean.class, Errors.class, TestBean.class,
|
||||
Color.class, HttpServletRequest.class, HttpServletResponse.class, User.class, OtherUser.class,
|
||||
Model.class };
|
||||
|
||||
/* URI template vars (see RequestMappingHandlerMethodMapping) */
|
||||
Map<String, String> uriTemplateVars = new HashMap<String, String>();
|
||||
uriTemplateVars.put("pathvar", "pathvarValue");
|
||||
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars);
|
||||
|
||||
Date date = new GregorianCalendar(2011, Calendar.MARCH, 16).getTime();
|
||||
String formattedDate = "2011.03.16";
|
||||
|
||||
System.setProperty("systemHeader", "systemHeaderValue");
|
||||
|
||||
request.setCookies(new Cookie("cookie", "99"));
|
||||
request.addHeader("header", "headerValue");
|
||||
request.addHeader("anotherHeader", "anotherHeaderValue");
|
||||
request.addParameter("datePattern", "yyyy.MM.dd");
|
||||
request.addParameter("dateParam", formattedDate);
|
||||
request.addParameter("paramByConvention", "paramByConventionValue");
|
||||
request.addParameter("age", "25");
|
||||
request.setContextPath("/contextPath");
|
||||
|
||||
request.addHeader("Content-Type", "text/plain; charset=utf-8");
|
||||
request.setContent("Hello World".getBytes("UTF-8"));
|
||||
|
||||
request.setUserPrincipal(new User());
|
||||
|
||||
HandlerMethod handlerMethod = handlerMethod(new RequestMappingHandler(), "handleMvc", paramTypes);
|
||||
ModelAndView mav = handlerAdapter.handle(request, response, handlerMethod);
|
||||
ModelMap model = mav.getModelMap();
|
||||
|
||||
assertEquals("viewName", mav.getViewName());
|
||||
assertEquals(99, model.get("cookie"));
|
||||
assertEquals("pathvarValue", model.get("pathvar"));
|
||||
assertEquals("headerValue", model.get("header"));
|
||||
assertEquals(date, model.get("dateParam"));
|
||||
|
||||
Map<?,?> map = (Map<?,?>) model.get("headerMap");
|
||||
assertEquals("headerValue", map.get("header"));
|
||||
assertEquals("anotherHeaderValue", map.get("anotherHeader"));
|
||||
assertEquals("systemHeaderValue", model.get("systemHeader"));
|
||||
|
||||
map = (Map<?,?>) model.get("paramMap");
|
||||
assertEquals(formattedDate, map.get("dateParam"));
|
||||
assertEquals("paramByConventionValue", map.get("paramByConvention"));
|
||||
|
||||
assertEquals("/contextPath", model.get("value"));
|
||||
|
||||
TestBean modelAttr = (TestBean) model.get("modelAttr");
|
||||
assertEquals(25, modelAttr.getAge());
|
||||
assertEquals("Set by model method [modelAttr]", modelAttr.getName());
|
||||
assertSame(modelAttr, request.getSession().getAttribute("modelAttr"));
|
||||
|
||||
BindingResult bindingResult = (BindingResult) model.get(BindingResult.MODEL_KEY_PREFIX + "modelAttr");
|
||||
assertSame(modelAttr, bindingResult.getTarget());
|
||||
assertEquals(1, bindingResult.getErrorCount());
|
||||
|
||||
String conventionAttrName = "testBean";
|
||||
TestBean modelAttrByConvention = (TestBean) model.get(conventionAttrName);
|
||||
assertEquals(25, modelAttrByConvention.getAge());
|
||||
assertEquals("Set by model method [modelAttrByConvention]", modelAttrByConvention.getName());
|
||||
assertSame(modelAttrByConvention, request.getSession().getAttribute(conventionAttrName));
|
||||
|
||||
bindingResult = (BindingResult) model.get(BindingResult.MODEL_KEY_PREFIX + conventionAttrName);
|
||||
assertSame(modelAttrByConvention, bindingResult.getTarget());
|
||||
|
||||
assertTrue(model.get("customArg") instanceof Color);
|
||||
assertEquals(User.class, model.get("user").getClass());
|
||||
assertEquals(OtherUser.class, model.get("otherUser").getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleRequestBody() throws Exception {
|
||||
Class<?>[] paramTypes = new Class<?>[] { byte[].class };
|
||||
|
||||
request.addHeader("Content-Type", "text/plain; charset=utf-8");
|
||||
request.setContent("Hello Server".getBytes("UTF-8"));
|
||||
|
||||
HandlerMethod handlerMethod = handlerMethod(new RequestMappingHandler(), "handleRequestBody", paramTypes);
|
||||
|
||||
ModelAndView mav = handlerAdapter.handle(request, response, handlerMethod);
|
||||
|
||||
assertNull(mav);
|
||||
assertEquals("Handled requestBody=[Hello Server]", new String(response.getContentAsByteArray(), "UTF-8"));
|
||||
assertEquals(HttpStatus.ACCEPTED.value(), response.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleHttpEntity() throws Exception {
|
||||
Class<?>[] paramTypes = new Class<?>[] { HttpEntity.class };
|
||||
|
||||
request.addHeader("Content-Type", "text/plain; charset=utf-8");
|
||||
request.setContent("Hello Server".getBytes("UTF-8"));
|
||||
|
||||
HandlerMethod handlerMethod = handlerMethod(new RequestMappingHandler(), "handleHttpEntity", paramTypes);
|
||||
|
||||
ModelAndView mav = handlerAdapter.handle(request, response, handlerMethod);
|
||||
|
||||
assertNull(mav);
|
||||
assertEquals(HttpStatus.ACCEPTED.value(), response.getStatus());
|
||||
assertEquals("Handled requestBody=[Hello Server]", new String(response.getContentAsByteArray(), "UTF-8"));
|
||||
assertEquals("headerValue", response.getHeader("header"));
|
||||
}
|
||||
|
||||
private HandlerMethod handlerMethod(Object handler, String methodName, Class<?>... paramTypes) throws Exception {
|
||||
Method method = handler.getClass().getDeclaredMethod(methodName, paramTypes);
|
||||
return new InvocableHandlerMethod(handler, method);
|
||||
}
|
||||
|
||||
@SessionAttributes(types=TestBean.class)
|
||||
private static class RequestMappingHandler {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@InitBinder("dateParam")
|
||||
public void initBinder(WebDataBinder dataBinder, @RequestParam("datePattern") String datePattern) {
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern);
|
||||
dataBinder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ModelAttribute
|
||||
public void model(Model model) {
|
||||
TestBean modelAttr = new TestBean();
|
||||
modelAttr.setName("Set by model method [modelAttr]");
|
||||
model.addAttribute("modelAttr", modelAttr);
|
||||
|
||||
modelAttr = new TestBean();
|
||||
modelAttr.setName("Set by model method [modelAttrByConvention]");
|
||||
model.addAttribute(modelAttr);
|
||||
|
||||
model.addAttribute(new OtherUser());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public String handleMvc(
|
||||
@CookieValue("cookie") int cookie,
|
||||
@PathVariable("pathvar") String pathvar,
|
||||
@RequestHeader("header") String header,
|
||||
@RequestHeader(defaultValue="#{systemProperties.systemHeader}") String systemHeader,
|
||||
@RequestHeader Map<String, Object> headerMap,
|
||||
@RequestParam("dateParam") Date dateParam,
|
||||
@RequestParam Map<String, Object> paramMap,
|
||||
String paramByConvention,
|
||||
@Value("#{request.contextPath}") String value,
|
||||
@ModelAttribute("modelAttr") @Valid TestBean modelAttr,
|
||||
Errors errors,
|
||||
TestBean modelAttrByConvention,
|
||||
Color customArg,
|
||||
HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
User user,
|
||||
@ModelAttribute OtherUser otherUser,
|
||||
Model model) throws Exception {
|
||||
|
||||
model.addAttribute("cookie", cookie).addAttribute("pathvar", pathvar).addAttribute("header", header)
|
||||
.addAttribute("systemHeader", systemHeader).addAttribute("headerMap", headerMap)
|
||||
.addAttribute("dateParam", dateParam).addAttribute("paramMap", paramMap)
|
||||
.addAttribute("paramByConvention", paramByConvention).addAttribute("value", value)
|
||||
.addAttribute("customArg", customArg).addAttribute(user);
|
||||
|
||||
assertNotNull(request);
|
||||
assertNotNull(response);
|
||||
|
||||
return "viewName";
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ResponseStatus(value=HttpStatus.ACCEPTED)
|
||||
@ResponseBody
|
||||
public String handleRequestBody(@RequestBody byte[] bytes) throws Exception {
|
||||
String requestBody = new String(bytes, "UTF-8");
|
||||
return "Handled requestBody=[" + requestBody + "]";
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public ResponseEntity<String> handleHttpEntity(HttpEntity<byte[]> httpEntity) throws Exception {
|
||||
HttpHeaders responseHeaders = new HttpHeaders();
|
||||
responseHeaders.set("header", "headerValue");
|
||||
String responseBody = "Handled requestBody=[" + new String(httpEntity.getBody(), "UTF-8") + "]";
|
||||
return new ResponseEntity<String>(responseBody, responseHeaders, HttpStatus.ACCEPTED);
|
||||
}
|
||||
}
|
||||
|
||||
private static class StubValidator implements Validator {
|
||||
public boolean supports(Class<?> clazz) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void validate(Object target, Errors errors) {
|
||||
errors.reject("error");
|
||||
}
|
||||
}
|
||||
|
||||
private static class ColorArgumentResolver implements WebArgumentResolver {
|
||||
public Object resolveArgument(MethodParameter methodParameter, NativeWebRequest webRequest) throws Exception {
|
||||
return new Color(0);
|
||||
}
|
||||
}
|
||||
|
||||
private static class User implements Principal {
|
||||
public String getName() {
|
||||
return "user";
|
||||
}
|
||||
}
|
||||
|
||||
private static class OtherUser implements Principal {
|
||||
public String getName() {
|
||||
return "other user";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.method.annotation;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.SessionAttributes;
|
||||
import org.springframework.web.context.support.GenericWebApplicationContext;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.method.support.InvocableHandlerMethod;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||
|
||||
/**
|
||||
* Test fixture for {@link RequestMappingHandlerAdapter} unit tests.
|
||||
*
|
||||
* The tests in this class focus on {@link RequestMappingHandlerAdapter} functionality exclusively.
|
||||
* Also see {@link RequestMappingHandlerAdapterIntegrationTests} for higher-level tests invoking
|
||||
* {@link Controller @Controller} methods.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class RequestMappingHandlerAdapterTests {
|
||||
|
||||
private RequestMappingHandlerAdapter handlerAdapter;
|
||||
|
||||
private MockHttpServletRequest request;
|
||||
|
||||
private MockHttpServletResponse response;
|
||||
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
this.handlerAdapter = new RequestMappingHandlerAdapter();
|
||||
this.handlerAdapter.setApplicationContext(new GenericWebApplicationContext());
|
||||
this.handlerAdapter.afterPropertiesSet();
|
||||
|
||||
this.request = new MockHttpServletRequest();
|
||||
this.response = new MockHttpServletResponse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cacheControlWithoutSessionAttributes() throws Exception {
|
||||
handlerAdapter.setCacheSeconds(100);
|
||||
handlerAdapter.handle(request, response, handlerMethod(new SimpleHandler(), "handle"));
|
||||
|
||||
assertTrue(response.getHeader("Cache-Control").toString().contains("max-age"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cacheControlWithSessionAttributes() throws Exception {
|
||||
handlerAdapter.setCacheSeconds(100);
|
||||
handlerAdapter.handle(request, response, handlerMethod(new SessionAttributeHandler(), "handle"));
|
||||
|
||||
assertEquals("no-cache", response.getHeader("Cache-Control"));
|
||||
}
|
||||
|
||||
private HandlerMethod handlerMethod(Object handler, String methodName, Class<?>... paramTypes) throws Exception {
|
||||
Method method = handler.getClass().getDeclaredMethod(methodName, paramTypes);
|
||||
return new InvocableHandlerMethod(handler, method);
|
||||
}
|
||||
|
||||
private static class SimpleHandler {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void handle() {
|
||||
}
|
||||
}
|
||||
|
||||
@SessionAttributes("attr1")
|
||||
private static class SessionAttributeHandler {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void handle() {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.method.annotation;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
import org.junit.runners.Parameterized.Parameters;
|
||||
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
|
||||
import org.springframework.aop.interceptor.SimpleTraceInterceptor;
|
||||
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.context.support.GenericWebApplicationContext;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodMapping;
|
||||
|
||||
/**
|
||||
* Test various scenarios for detecting handler methods depending on where @RequestMapping annotations
|
||||
* are located -- super types, parameterized methods, or in combination with proxies.
|
||||
*
|
||||
* Note the following:
|
||||
* <ul>
|
||||
* <li>Parameterized methods cannot be used in combination with JDK dynamic proxies since the
|
||||
* proxy interface does not contain the bridged methods that need to be invoked.
|
||||
* <li>When using JDK dynamic proxies, the proxied interface must contain all required annotations.
|
||||
* <li>Method-level annotations can be placed on parent classes or interfaces.
|
||||
* </ul>
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
@RunWith(Parameterized.class)
|
||||
public class RequestMappingHandlerMethodDetectionTests {
|
||||
|
||||
@Parameters
|
||||
public static Collection<Object[]> handlerTypes() {
|
||||
return Arrays.asList(new Object[][] {
|
||||
{ new MappingInterfaceController(), false},
|
||||
{ new MappingAbstractClassController(), false},
|
||||
{ new ParameterizedInterfaceController(), false },
|
||||
{ new MappingParameterizedInterfaceController(), false },
|
||||
{ new MappingAbstractClassController(), true},
|
||||
{ new PlainController(), true}
|
||||
});
|
||||
}
|
||||
|
||||
private Object handler;
|
||||
|
||||
private boolean useAutoProxy;
|
||||
|
||||
public RequestMappingHandlerMethodDetectionTests(Object handler, boolean useAutoProxy) {
|
||||
this.handler = handler;
|
||||
this.useAutoProxy = useAutoProxy;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void detectAndMapHandlerMethod() throws Exception {
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/handle");
|
||||
|
||||
TestRequestMappingHandlerMethodMapping mapping = createHandlerMapping(handler.getClass(), useAutoProxy);
|
||||
HandlerMethod handlerMethod = mapping.getHandlerInternal(request);
|
||||
|
||||
assertNotNull("Failed to detect and map @RequestMapping handler method", handlerMethod);
|
||||
}
|
||||
|
||||
private TestRequestMappingHandlerMethodMapping createHandlerMapping(Class<?> controllerType, boolean useAutoProxy) {
|
||||
GenericWebApplicationContext wac = new GenericWebApplicationContext();
|
||||
wac.registerBeanDefinition("controller", new RootBeanDefinition(controllerType));
|
||||
if (useAutoProxy) {
|
||||
DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
|
||||
autoProxyCreator.setBeanFactory(wac.getBeanFactory());
|
||||
wac.getBeanFactory().addBeanPostProcessor(autoProxyCreator);
|
||||
wac.getBeanFactory().registerSingleton("advsr", new DefaultPointcutAdvisor(new SimpleTraceInterceptor()));
|
||||
}
|
||||
|
||||
TestRequestMappingHandlerMethodMapping mapping = new TestRequestMappingHandlerMethodMapping();
|
||||
mapping.setApplicationContext(wac);
|
||||
|
||||
return mapping;
|
||||
}
|
||||
|
||||
public static class TestRequestMappingHandlerMethodMapping extends RequestMappingHandlerMethodMapping {
|
||||
public HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
|
||||
return super.getHandlerInternal(request);
|
||||
}
|
||||
}
|
||||
|
||||
@Controller
|
||||
public interface MappingInterface {
|
||||
@RequestMapping(value="/handle", method = RequestMethod.GET)
|
||||
void handle();
|
||||
}
|
||||
|
||||
public static class MappingInterfaceController implements MappingInterface {
|
||||
public void handle() {
|
||||
}
|
||||
}
|
||||
|
||||
@Controller
|
||||
public static abstract class MappingAbstractClass {
|
||||
@RequestMapping(value = "/handle", method = RequestMethod.GET)
|
||||
public abstract void handle();
|
||||
}
|
||||
|
||||
public static class MappingAbstractClassController extends MappingAbstractClass {
|
||||
public void handle() {
|
||||
}
|
||||
}
|
||||
|
||||
@Controller
|
||||
public interface ParameterizedInterface<T> {
|
||||
void handle(T object);
|
||||
}
|
||||
|
||||
public static class ParameterizedInterfaceController implements ParameterizedInterface<TestBean> {
|
||||
@RequestMapping(value = "/handle", method = RequestMethod.GET)
|
||||
public void handle(TestBean object) {
|
||||
}
|
||||
}
|
||||
|
||||
@Controller
|
||||
public interface MappingParameterizedInterface<T> {
|
||||
@RequestMapping(value = "/handle", method = RequestMethod.GET)
|
||||
void handle(T object);
|
||||
}
|
||||
|
||||
public static class MappingParameterizedInterfaceController implements MappingParameterizedInterface<TestBean> {
|
||||
public void handle(TestBean object) {
|
||||
}
|
||||
}
|
||||
|
||||
@Controller
|
||||
public static class PlainController {
|
||||
public PlainController() {
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/handle", method = RequestMethod.GET)
|
||||
public void handle() {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.method.annotation;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.Writer;
|
||||
import java.net.BindException;
|
||||
import java.net.SocketException;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.method.support.InvocableHandlerMethod;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodExceptionResolver;
|
||||
|
||||
/**
|
||||
* Test fixture for {@link RequestMappingHandlerMethodExceptionResolver} unit tests.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Arjen Poutsma
|
||||
* @since 3.1
|
||||
*/
|
||||
public class RequestMappingHandlerMethodExceptionResolverTests {
|
||||
|
||||
private RequestMappingHandlerMethodExceptionResolver exceptionResolver;
|
||||
|
||||
private MockHttpServletRequest request;
|
||||
|
||||
private MockHttpServletResponse response;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
exceptionResolver = new RequestMappingHandlerMethodExceptionResolver();
|
||||
exceptionResolver.afterPropertiesSet();
|
||||
request = new MockHttpServletRequest();
|
||||
response = new MockHttpServletResponse();
|
||||
request.setMethod("GET");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleWithIOException() throws NoSuchMethodException {
|
||||
IOException ex = new IOException();
|
||||
HandlerMethod handlerMethod = new InvocableHandlerMethod(new SimpleController(), "handle");
|
||||
ModelAndView mav = exceptionResolver.resolveException(request, response, handlerMethod, ex);
|
||||
assertNotNull("No ModelAndView returned", mav);
|
||||
assertEquals("Invalid view name returned", "X:IOException", mav.getViewName());
|
||||
assertEquals("Invalid status code returned", 500, response.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleWithSocketException() throws NoSuchMethodException {
|
||||
SocketException ex = new SocketException();
|
||||
HandlerMethod handlerMethod = new InvocableHandlerMethod(new SimpleController(), "handle");
|
||||
ModelAndView mav = exceptionResolver.resolveException(request, response, handlerMethod, ex);
|
||||
assertNotNull("No ModelAndView returned", mav);
|
||||
assertEquals("Invalid view name returned", "Y:SocketException", mav.getViewName());
|
||||
assertEquals("Invalid status code returned", 406, response.getStatus());
|
||||
assertEquals("Invalid status reason returned", "This is simply unacceptable!", response.getErrorMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleWithFileNotFoundException() throws NoSuchMethodException {
|
||||
FileNotFoundException ex = new FileNotFoundException();
|
||||
HandlerMethod handlerMethod = new InvocableHandlerMethod(new SimpleController(), "handle");
|
||||
ModelAndView mav = exceptionResolver.resolveException(request, response, handlerMethod, ex);
|
||||
assertNotNull("No ModelAndView returned", mav);
|
||||
assertEquals("Invalid view name returned", "X:FileNotFoundException", mav.getViewName());
|
||||
assertEquals("Invalid status code returned", 500, response.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleWithBindException() throws NoSuchMethodException {
|
||||
BindException ex = new BindException();
|
||||
HandlerMethod handlerMethod = new InvocableHandlerMethod(new SimpleController(), "handle");
|
||||
ModelAndView mav = exceptionResolver.resolveException(request, response, handlerMethod, ex);
|
||||
assertNotNull("No ModelAndView returned", mav);
|
||||
assertEquals("Invalid view name returned", "Y:BindException", mav.getViewName());
|
||||
assertEquals("Invalid status code returned", 406, response.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void inherited() throws NoSuchMethodException {
|
||||
IOException ex = new IOException();
|
||||
HandlerMethod handlerMethod = new InvocableHandlerMethod(new InheritedController(), "handle");
|
||||
ModelAndView mav = exceptionResolver.resolveException(request, response, handlerMethod, ex);
|
||||
assertNotNull("No ModelAndView returned", mav);
|
||||
assertEquals("Invalid view name returned", "GenericError", mav.getViewName());
|
||||
assertEquals("Invalid status code returned", 500, response.getStatus());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void ambiguous() throws NoSuchMethodException {
|
||||
IllegalArgumentException ex = new IllegalArgumentException();
|
||||
HandlerMethod handlerMethod = new InvocableHandlerMethod(new AmbiguousController(), "handle");
|
||||
exceptionResolver.resolveException(request, response, handlerMethod, ex);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noModelAndView() throws UnsupportedEncodingException, NoSuchMethodException {
|
||||
IllegalArgumentException ex = new IllegalArgumentException();
|
||||
HandlerMethod handlerMethod = new InvocableHandlerMethod(new NoMAVReturningController(), "handle");
|
||||
ModelAndView mav = exceptionResolver.resolveException(request, response, handlerMethod, ex);
|
||||
assertNotNull("No ModelAndView returned", mav);
|
||||
assertTrue("ModelAndView not empty", mav.isEmpty());
|
||||
assertEquals("Invalid response written", "IllegalArgumentException", response.getContentAsString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void responseBody() throws UnsupportedEncodingException, NoSuchMethodException {
|
||||
IllegalArgumentException ex = new IllegalArgumentException();
|
||||
HandlerMethod handlerMethod = new InvocableHandlerMethod(new ResponseBodyController(), "handle");
|
||||
request.addHeader("Accept", "text/plain");
|
||||
ModelAndView mav = exceptionResolver.resolveException(request, response, handlerMethod, ex);
|
||||
assertNotNull("No ModelAndView returned", mav);
|
||||
assertTrue("ModelAndView not empty", mav.isEmpty());
|
||||
assertEquals("Invalid response written", "IllegalArgumentException", response.getContentAsString());
|
||||
}
|
||||
|
||||
|
||||
@Controller
|
||||
private static class SimpleController {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void handle() {}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ExceptionHandler(IOException.class)
|
||||
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||
public String handleIOException(IOException ex, HttpServletRequest request) {
|
||||
return "X:" + ClassUtils.getShortName(ex.getClass());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ExceptionHandler(SocketException.class)
|
||||
@ResponseStatus(value = HttpStatus.NOT_ACCEPTABLE, reason = "This is simply unacceptable!")
|
||||
public String handleSocketException(Exception ex, HttpServletResponse response) {
|
||||
return "Y:" + ClassUtils.getShortName(ex.getClass());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ExceptionHandler(IllegalArgumentException.class)
|
||||
public String handleIllegalArgumentException(Exception ex) {
|
||||
return ClassUtils.getShortName(ex.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Controller
|
||||
private static class InheritedController extends SimpleController {
|
||||
|
||||
@Override
|
||||
public String handleIOException(IOException ex, HttpServletRequest request) {
|
||||
return "GenericError";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Controller
|
||||
private static class AmbiguousController {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void handle() {}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ExceptionHandler({BindException.class, IllegalArgumentException.class})
|
||||
public String handle1(Exception ex, HttpServletRequest request, HttpServletResponse response)
|
||||
throws IOException {
|
||||
return ClassUtils.getShortName(ex.getClass());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ExceptionHandler
|
||||
public String handle2(IllegalArgumentException ex) {
|
||||
return ClassUtils.getShortName(ex.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Controller
|
||||
private static class NoMAVReturningController {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void handle() {}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ExceptionHandler(Exception.class)
|
||||
public void handle(Exception ex, Writer writer) throws IOException {
|
||||
writer.write(ClassUtils.getShortName(ex.getClass()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Controller
|
||||
private static class ResponseBodyController {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void handle() {}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ExceptionHandler(Exception.class)
|
||||
@ResponseBody
|
||||
public String handle(Exception ex) {
|
||||
return ClassUtils.getShortName(ex.getClass());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.method.annotation;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.HandlerExecutionChain;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
|
||||
import org.springframework.web.servlet.handler.MappedInterceptor;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestKey;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodMapping;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class RequestMappingHandlerMethodMappingTests {
|
||||
|
||||
private MyRequestMappingHandlerMethodMapping mapping;
|
||||
|
||||
private MyHandler handler;
|
||||
|
||||
private HandlerMethod fooMethod;
|
||||
|
||||
private HandlerMethod barMethod;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
handler = new MyHandler();
|
||||
fooMethod = new HandlerMethod(handler, "foo");
|
||||
barMethod = new HandlerMethod(handler, "bar");
|
||||
|
||||
StaticApplicationContext context = new StaticApplicationContext();
|
||||
context.registerSingleton("handler", handler.getClass());
|
||||
|
||||
mapping = new MyRequestMappingHandlerMethodMapping();
|
||||
mapping.setApplicationContext(context);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void directMatch() throws Exception {
|
||||
HandlerMethod result = mapping.getHandlerInternal(new MockHttpServletRequest("GET", "/foo"));
|
||||
assertEquals(fooMethod.getMethod(), result.getMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void globMatch() throws Exception {
|
||||
HandlerMethod result = mapping.getHandlerInternal(new MockHttpServletRequest("GET", "/bar"));
|
||||
assertEquals(barMethod.getMethod(), result.getMethod());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodNotAllowed() throws Exception {
|
||||
try {
|
||||
mapping.getHandlerInternal(new MockHttpServletRequest("POST", "/bar"));
|
||||
fail("HttpRequestMethodNotSupportedException expected");
|
||||
}
|
||||
catch (HttpRequestMethodNotSupportedException ex) {
|
||||
assertArrayEquals("Invalid supported methods", new String[]{"GET", "HEAD"}, ex.getSupportedMethods());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void uriTemplateVariables() {
|
||||
RequestKey key = new RequestKey(Arrays.asList("/{path1}/{path2}"), null, null, null);
|
||||
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/1/2");
|
||||
|
||||
mapping.handleMatch(key, request);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, String> actual = (Map<String, String>) request.getAttribute(
|
||||
HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
|
||||
|
||||
assertNotNull(actual);
|
||||
assertEquals("1", actual.get("path1"));
|
||||
assertEquals("2", actual.get("path2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mappedInterceptors() {
|
||||
String path = "/handle";
|
||||
HandlerInterceptor interceptor = new HandlerInterceptorAdapter() {};
|
||||
MappedInterceptor mappedInterceptor = new MappedInterceptor(new String[] {path}, interceptor);
|
||||
|
||||
MyRequestMappingHandlerMethodMapping mapping = new MyRequestMappingHandlerMethodMapping();
|
||||
mapping.setMappedInterceptors(new MappedInterceptor[] { mappedInterceptor });
|
||||
|
||||
HandlerExecutionChain chain = mapping.getHandlerExecutionChain(handler, new MockHttpServletRequest("GET", path));
|
||||
assertNotNull(chain.getInterceptors());
|
||||
assertSame(interceptor, chain.getInterceptors()[0]);
|
||||
|
||||
chain = mapping.getHandlerExecutionChain(handler, new MockHttpServletRequest("GET", "/invalid"));
|
||||
assertNull(chain.getInterceptors());
|
||||
}
|
||||
|
||||
private static class MyRequestMappingHandlerMethodMapping extends RequestMappingHandlerMethodMapping {
|
||||
|
||||
@Override
|
||||
public HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
|
||||
return super.getHandlerInternal(request);
|
||||
}
|
||||
}
|
||||
|
||||
@Controller
|
||||
private static class MyHandler {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@RequestMapping(value = "/foo", method = RequestMethod.GET)
|
||||
public void foo() {
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@RequestMapping(value = "/ba*", method = { RequestMethod.GET, RequestMethod.HEAD })
|
||||
public void bar() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.method.annotation;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandlerContainer;
|
||||
import org.springframework.web.method.support.StubReturnValueHandler;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod;
|
||||
|
||||
/**
|
||||
* Test fixture for {@link ServletInvocableHandlerMethod} unit tests.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class ServletInvocableHandlerMethodTests {
|
||||
|
||||
private ServletWebRequest webRequest;
|
||||
|
||||
private MockHttpServletResponse response;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
response = new MockHttpServletResponse();
|
||||
this.webRequest = new ServletWebRequest(new MockHttpServletRequest(), response);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setResponseStatus() throws Exception {
|
||||
HandlerMethodReturnValueHandlerContainer handlers = new HandlerMethodReturnValueHandlerContainer();
|
||||
handlers.registerReturnValueHandler(new StubReturnValueHandler(void.class, false));
|
||||
|
||||
Method method = Handler.class.getDeclaredMethod("responseStatus");
|
||||
ServletInvocableHandlerMethod handlerMethod = new ServletInvocableHandlerMethod(new Handler(), method);
|
||||
handlerMethod.setReturnValueHandlers(handlers);
|
||||
|
||||
handlerMethod.invokeAndHandle(webRequest, null);
|
||||
|
||||
assertEquals(HttpStatus.BAD_REQUEST.value(), response.getStatus());
|
||||
assertEquals("400 Bad Request", response.getErrorMessage());
|
||||
}
|
||||
|
||||
private static class Handler {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "400 Bad Request")
|
||||
public void responseStatus() {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.method.annotation.support;
|
||||
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
import org.springframework.web.servlet.View;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.support.DefaultMethodReturnValueHandler;
|
||||
|
||||
/**
|
||||
* Test fixture for {@link DefaultMethodReturnValueHandler} unit tests.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class DefaultMethodReturnValueHandlerTests {
|
||||
|
||||
private DefaultMethodReturnValueHandler handler;
|
||||
|
||||
private ServletWebRequest webRequest;
|
||||
|
||||
private ModelAndViewContainer<View> mavContainer;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.handler = new DefaultMethodReturnValueHandler(null);
|
||||
this.mavContainer = new ModelAndViewContainer<View>(new ExtendedModelMap());
|
||||
this.webRequest = new ServletWebRequest(new MockHttpServletRequest());
|
||||
}
|
||||
|
||||
@Test(expected=UnsupportedOperationException.class)
|
||||
public void returnSimpleType() throws Exception {
|
||||
handler.handleReturnValue(55, createMethodParam("simpleType"), mavContainer, webRequest);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnVoid() throws Exception {
|
||||
handler.handleReturnValue(null, null, mavContainer, webRequest);
|
||||
assertNull(mavContainer.getView());
|
||||
assertNull(mavContainer.getViewName());
|
||||
assertTrue(mavContainer.getModel().isEmpty());
|
||||
}
|
||||
|
||||
private MethodParameter createMethodParam(String methodName) throws Exception {
|
||||
Method method = getClass().getDeclaredMethod(methodName);
|
||||
return new MethodParameter(method, -1);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private int simpleType() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private void voidReturnValue() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.method.annotation.support;
|
||||
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.eq;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.isA;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.http.HttpEntity;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.support.HttpEntityMethodProcessor;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class HttpEntityMethodProcessorTests {
|
||||
|
||||
private HttpEntityMethodProcessor processor;
|
||||
|
||||
private HttpMessageConverter<String> messageConverter;
|
||||
|
||||
private MethodParameter httpEntityParam;
|
||||
|
||||
private MethodParameter responseEntityReturnValue;
|
||||
|
||||
private MethodParameter responseEntityParameter;
|
||||
|
||||
private MethodParameter intReturnValue;
|
||||
|
||||
private ServletWebRequest request;
|
||||
|
||||
private MockHttpServletRequest servletRequest;
|
||||
|
||||
private MockHttpServletResponse servletResponse;
|
||||
|
||||
private MethodParameter httpEntityReturnValue;
|
||||
|
||||
private MethodParameter intParameter;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
messageConverter = createMock(HttpMessageConverter.class);
|
||||
processor = new HttpEntityMethodProcessor(messageConverter);
|
||||
|
||||
Method handle1 = getClass().getMethod("handle1", HttpEntity.class, ResponseEntity.class, Integer.TYPE);
|
||||
httpEntityParam = new MethodParameter(handle1, 0);
|
||||
responseEntityParameter = new MethodParameter(handle1, 1);
|
||||
intParameter = new MethodParameter(handle1, 2);
|
||||
responseEntityReturnValue = new MethodParameter(handle1, -1);
|
||||
|
||||
Method handle2 = getClass().getMethod("handle2", HttpEntity.class);
|
||||
httpEntityReturnValue = new MethodParameter(handle2, -1);
|
||||
|
||||
Method other = getClass().getMethod("otherMethod");
|
||||
intReturnValue = new MethodParameter(other, -1);
|
||||
|
||||
servletRequest = new MockHttpServletRequest();
|
||||
servletResponse = new MockHttpServletResponse();
|
||||
request = new ServletWebRequest(servletRequest, servletResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsParameter() {
|
||||
assertTrue("HttpEntity parameter not supported", processor.supportsParameter(httpEntityParam));
|
||||
assertFalse("ResponseEntity parameter supported", processor.supportsParameter(responseEntityParameter));
|
||||
assertFalse("non-entity parameter supported", processor.supportsParameter(intParameter));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsReturnType() {
|
||||
assertTrue("ResponseEntity return type not supported", processor.supportsReturnType(responseEntityReturnValue));
|
||||
assertTrue("HttpEntity return type not supported", processor.supportsReturnType(httpEntityReturnValue));
|
||||
assertFalse("non-ResponseBody return type supported", processor.supportsReturnType(intReturnValue));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void usesResponseArgument() {
|
||||
assertFalse("HttpEntity parameter uses response argument", processor.usesResponseArgument(httpEntityParam));
|
||||
assertTrue("ResponseBody return type does not use response argument",
|
||||
processor.usesResponseArgument(responseEntityReturnValue));
|
||||
assertTrue("HttpEntity return type does not use response argument",
|
||||
processor.usesResponseArgument(httpEntityReturnValue));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void resolveArgument() throws Exception {
|
||||
MediaType contentType = MediaType.TEXT_PLAIN;
|
||||
String expected = "Foo";
|
||||
|
||||
servletRequest.addHeader("Content-Type", contentType.toString());
|
||||
|
||||
expect(messageConverter.getSupportedMediaTypes()).andReturn(Arrays.asList(contentType));
|
||||
expect(messageConverter.canRead(String.class, contentType)).andReturn(true);
|
||||
expect(messageConverter.read(eq(String.class), isA(HttpInputMessage.class))).andReturn(expected);
|
||||
|
||||
replay(messageConverter);
|
||||
|
||||
HttpEntity<?> result = (HttpEntity<String>) processor.resolveArgument(httpEntityParam, null, request, null);
|
||||
assertEquals("Invalid argument", expected, result.getBody());
|
||||
|
||||
verify(messageConverter);
|
||||
}
|
||||
|
||||
@Test(expected = HttpMediaTypeNotSupportedException.class)
|
||||
public void resolveArgumentNotReadable() throws Exception {
|
||||
MediaType contentType = MediaType.TEXT_PLAIN;
|
||||
|
||||
servletRequest.addHeader("Content-Type", contentType.toString());
|
||||
|
||||
expect(messageConverter.getSupportedMediaTypes()).andReturn(Arrays.asList(contentType));
|
||||
expect(messageConverter.canRead(String.class, contentType)).andReturn(false);
|
||||
|
||||
replay(messageConverter);
|
||||
|
||||
processor.resolveArgument(httpEntityParam, null, request, null);
|
||||
|
||||
verify(messageConverter);
|
||||
}
|
||||
|
||||
@Test(expected = HttpMediaTypeNotSupportedException.class)
|
||||
public void resolveArgumentNoContentType() throws Exception {
|
||||
processor.resolveArgument(httpEntityParam, null, request, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleReturnValue() throws Exception {
|
||||
MediaType accepted = MediaType.TEXT_PLAIN;
|
||||
String s = "Foo";
|
||||
ResponseEntity<String> returnValue = new ResponseEntity<String>(s, HttpStatus.OK);
|
||||
|
||||
servletRequest.addHeader("Accept", accepted.toString());
|
||||
|
||||
expect(messageConverter.canWrite(String.class, accepted)).andReturn(true);
|
||||
messageConverter.write(eq(s), eq(accepted), isA(HttpOutputMessage.class));
|
||||
|
||||
replay(messageConverter);
|
||||
|
||||
processor.handleReturnValue(returnValue, responseEntityReturnValue, null, request);
|
||||
|
||||
verify(messageConverter);
|
||||
}
|
||||
|
||||
@Test(expected = HttpMediaTypeNotAcceptableException.class)
|
||||
public void handleReturnValueNotAcceptable() throws Exception {
|
||||
MediaType accepted = MediaType.TEXT_PLAIN;
|
||||
String s = "Foo";
|
||||
ResponseEntity<String> returnValue = new ResponseEntity<String>(s, HttpStatus.OK);
|
||||
|
||||
servletRequest.addHeader("Accept", accepted.toString());
|
||||
|
||||
expect(messageConverter.canWrite(String.class, accepted)).andReturn(false);
|
||||
expect(messageConverter.getSupportedMediaTypes()).andReturn(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM));
|
||||
|
||||
replay(messageConverter);
|
||||
|
||||
processor.handleReturnValue(returnValue, responseEntityReturnValue, null, request);
|
||||
|
||||
verify(messageConverter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void responseHeaderNoBody() throws Exception {
|
||||
HttpHeaders responseHeaders = new HttpHeaders();
|
||||
responseHeaders.set("header", "headerValue");
|
||||
ResponseEntity<String> returnValue = new ResponseEntity<String>(responseHeaders, HttpStatus.ACCEPTED);
|
||||
|
||||
HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(new StringHttpMessageConverter());
|
||||
processor.handleReturnValue(returnValue, responseEntityReturnValue, null, request);
|
||||
|
||||
assertEquals("headerValue", servletResponse.getHeader("header"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void responseHeaderAndBody() throws Exception {
|
||||
HttpHeaders responseHeaders = new HttpHeaders();
|
||||
responseHeaders.set("header", "headerValue");
|
||||
ResponseEntity<String> returnValue = new ResponseEntity<String>("body", responseHeaders, HttpStatus.ACCEPTED);
|
||||
|
||||
HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(new StringHttpMessageConverter());
|
||||
processor.handleReturnValue(returnValue, responseEntityReturnValue, null, request);
|
||||
|
||||
assertEquals("headerValue", servletResponse.getHeader("header"));
|
||||
}
|
||||
|
||||
public ResponseEntity<String> handle1(HttpEntity<String> httpEntity, ResponseEntity<String> responseEntity, int i) {
|
||||
return responseEntity;
|
||||
}
|
||||
|
||||
public HttpEntity<?> handle2(HttpEntity<?> entity) {
|
||||
return entity;
|
||||
}
|
||||
|
||||
public HttpEntity<?> handle3() {
|
||||
HttpHeaders responseHeaders = new HttpHeaders();
|
||||
responseHeaders.set("header", "headerValue");
|
||||
return new ResponseEntity<String>(responseHeaders, HttpStatus.OK);
|
||||
}
|
||||
|
||||
public int otherMethod() {
|
||||
return 42;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.method.annotation.support;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.support.PathVariableMethodArgumentResolver;
|
||||
|
||||
/**
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class PathVariableMethodArgumentResolverTests {
|
||||
|
||||
private PathVariableMethodArgumentResolver resolver;
|
||||
|
||||
private MethodParameter pathVarParam;
|
||||
|
||||
private MethodParameter stringParam;
|
||||
|
||||
private MockHttpServletRequest servletRequest;
|
||||
|
||||
private ServletWebRequest webRequest;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
resolver = new PathVariableMethodArgumentResolver(null);
|
||||
Method method = getClass().getMethod("handle", String.class, String.class);
|
||||
pathVarParam = new MethodParameter(method, 0);
|
||||
stringParam = new MethodParameter(method, 1);
|
||||
|
||||
servletRequest = new MockHttpServletRequest();
|
||||
MockHttpServletResponse servletResponse = new MockHttpServletResponse();
|
||||
webRequest = new ServletWebRequest(servletRequest, servletResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void usesResponseArgument() {
|
||||
assertFalse(resolver.usesResponseArgument(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsParameter() {
|
||||
assertTrue("Parameter with @PathVariable annotation", resolver.supportsParameter(pathVarParam));
|
||||
assertFalse("Parameter without @PathVariable annotation", resolver.supportsParameter(stringParam));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveStringArgument() throws Exception {
|
||||
String expected = "foo";
|
||||
|
||||
Map<String, String> uriTemplateVars = new HashMap<String, String>();
|
||||
uriTemplateVars.put("name", expected);
|
||||
servletRequest.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars);
|
||||
|
||||
String result = (String) resolver.resolveArgument(pathVarParam, null, webRequest, null);
|
||||
assertEquals(expected, result);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void handleMissingValue() throws Exception {
|
||||
resolver.resolveArgument(pathVarParam, null, webRequest, null);
|
||||
fail("Unresolved path variable should lead to exception.");
|
||||
}
|
||||
|
||||
public void handle(@PathVariable(value = "name") String param1, String param2) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.method.annotation.support;
|
||||
|
||||
import static org.easymock.EasyMock.createMock;
|
||||
import static org.easymock.EasyMock.eq;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.isA;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||
import org.springframework.web.HttpMediaTypeNotSupportedException;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.support.RequestResponseBodyMethodProcessor;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class RequestResponseBodyMethodProcessorTests {
|
||||
|
||||
private RequestResponseBodyMethodProcessor processor;
|
||||
|
||||
private HttpMessageConverter<String> messageConverter;
|
||||
|
||||
private MethodParameter stringParameter;
|
||||
|
||||
private MethodParameter stringReturnValue;
|
||||
|
||||
private MethodParameter intParameter;
|
||||
|
||||
private MethodParameter intReturnValue;
|
||||
|
||||
private NativeWebRequest webRequest;
|
||||
|
||||
private MockHttpServletRequest servletRequest;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
messageConverter = createMock(HttpMessageConverter.class);
|
||||
processor = new RequestResponseBodyMethodProcessor(messageConverter);
|
||||
Method handle = getClass().getMethod("handle", String.class, Integer.TYPE);
|
||||
stringParameter = new MethodParameter(handle, 0);
|
||||
intParameter = new MethodParameter(handle, 1);
|
||||
stringReturnValue = new MethodParameter(handle, -1);
|
||||
Method other = getClass().getMethod("otherMethod");
|
||||
intReturnValue = new MethodParameter(other, -1);
|
||||
|
||||
servletRequest = new MockHttpServletRequest();
|
||||
MockHttpServletResponse servletResponse = new MockHttpServletResponse();
|
||||
webRequest = new ServletWebRequest(servletRequest, servletResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsParameter() {
|
||||
assertTrue("RequestBody parameter not supported", processor.supportsParameter(stringParameter));
|
||||
assertFalse("non-RequestBody parameter supported", processor.supportsParameter(intParameter));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsReturnType() {
|
||||
assertTrue("ResponseBody return type not supported", processor.supportsReturnType(stringReturnValue));
|
||||
assertFalse("non-ResponseBody return type supported", processor.supportsReturnType(intReturnValue));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void usesResponseArgument() {
|
||||
assertFalse("RequestBody parameter uses response argument", processor.usesResponseArgument(stringParameter));
|
||||
assertTrue("ResponseBody return type does not use response argument",
|
||||
processor.usesResponseArgument(stringReturnValue));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveArgument() throws Exception {
|
||||
MediaType contentType = MediaType.TEXT_PLAIN;
|
||||
String expected = "Foo";
|
||||
|
||||
servletRequest.addHeader("Content-Type", contentType.toString());
|
||||
|
||||
expect(messageConverter.getSupportedMediaTypes()).andReturn(Arrays.asList(contentType));
|
||||
expect(messageConverter.canRead(String.class, contentType)).andReturn(true);
|
||||
expect(messageConverter.read(eq(String.class), isA(HttpInputMessage.class))).andReturn(expected);
|
||||
|
||||
replay(messageConverter);
|
||||
|
||||
Object result = processor.resolveArgument(stringParameter, null, webRequest, null);
|
||||
assertEquals("Invalid argument", expected, result);
|
||||
|
||||
verify(messageConverter);
|
||||
|
||||
}
|
||||
|
||||
@Test(expected = HttpMediaTypeNotSupportedException.class)
|
||||
public void resolveArgumentNotReadable() throws Exception {
|
||||
MediaType contentType = MediaType.TEXT_PLAIN;
|
||||
|
||||
servletRequest.addHeader("Content-Type", contentType.toString());
|
||||
|
||||
expect(messageConverter.getSupportedMediaTypes()).andReturn(Arrays.asList(contentType));
|
||||
expect(messageConverter.canRead(String.class, contentType)).andReturn(false);
|
||||
|
||||
replay(messageConverter);
|
||||
|
||||
processor.resolveArgument(stringParameter, null, webRequest, null);
|
||||
|
||||
verify(messageConverter);
|
||||
}
|
||||
|
||||
@Test(expected = HttpMediaTypeNotSupportedException.class)
|
||||
public void resolveArgumentNoContentType() throws Exception {
|
||||
processor.resolveArgument(stringParameter, null, webRequest, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleReturnValue() throws Exception {
|
||||
MediaType accepted = MediaType.TEXT_PLAIN;
|
||||
String returnValue = "Foo";
|
||||
|
||||
servletRequest.addHeader("Accept", accepted.toString());
|
||||
|
||||
expect(messageConverter.canWrite(String.class, accepted)).andReturn(true);
|
||||
messageConverter.write(eq(returnValue), eq(accepted), isA(HttpOutputMessage.class));
|
||||
|
||||
replay(messageConverter);
|
||||
|
||||
processor.handleReturnValue(returnValue, stringReturnValue, null, webRequest);
|
||||
|
||||
verify(messageConverter);
|
||||
}
|
||||
|
||||
@Test(expected = HttpMediaTypeNotAcceptableException.class)
|
||||
public void handleReturnValueNotAcceptable() throws Exception {
|
||||
MediaType accepted = MediaType.TEXT_PLAIN;
|
||||
String returnValue = "Foo";
|
||||
|
||||
servletRequest.addHeader("Accept", accepted.toString());
|
||||
|
||||
expect(messageConverter.canWrite(String.class, accepted)).andReturn(false);
|
||||
expect(messageConverter.getSupportedMediaTypes()).andReturn(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM));
|
||||
|
||||
replay(messageConverter);
|
||||
|
||||
processor.handleReturnValue(returnValue, stringReturnValue, null, webRequest);
|
||||
|
||||
verify(messageConverter);
|
||||
}
|
||||
|
||||
@ResponseBody
|
||||
public String handle(@RequestBody String s, int i) {
|
||||
return s;
|
||||
}
|
||||
|
||||
public int otherMethod() {
|
||||
return 42;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.method.annotation.support;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.web.bind.annotation.CookieValue;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.method.annotation.support.CookieValueMethodArgumentResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.support.ServletCookieValueMethodArgumentResolver;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class ServletCookieValueMethodArgumentResolverTests {
|
||||
|
||||
private CookieValueMethodArgumentResolver resolver;
|
||||
|
||||
private MethodParameter cookieParameter;
|
||||
|
||||
private MethodParameter cookieStringParameter;
|
||||
|
||||
private MethodParameter otherParameter;
|
||||
|
||||
private MockHttpServletRequest servletRequest;
|
||||
|
||||
private ServletWebRequest webRequest;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
resolver = new ServletCookieValueMethodArgumentResolver(null);
|
||||
Method method = getClass().getMethod("params", Cookie.class, String.class, String.class);
|
||||
cookieParameter = new MethodParameter(method, 0);
|
||||
cookieStringParameter = new MethodParameter(method, 1);
|
||||
otherParameter = new MethodParameter(method, 2);
|
||||
|
||||
servletRequest = new MockHttpServletRequest();
|
||||
MockHttpServletResponse servletResponse = new MockHttpServletResponse();
|
||||
webRequest = new ServletWebRequest(servletRequest, servletResponse);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void usesResponseArgument() throws NoSuchMethodException {
|
||||
assertFalse("resolver uses response argument", resolver.usesResponseArgument(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsParameter() {
|
||||
assertTrue("Cookie parameter not supported", resolver.supportsParameter(cookieParameter));
|
||||
assertTrue("Cookie string parameter not supported", resolver.supportsParameter(cookieStringParameter));
|
||||
assertFalse("non-@CookieValue parameter supported", resolver.supportsParameter(otherParameter));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveCookieArgument() throws Exception {
|
||||
Cookie expected = new Cookie("name", "foo");
|
||||
servletRequest.setCookies(expected);
|
||||
|
||||
Cookie result = (Cookie) resolver.resolveArgument(cookieParameter, null, webRequest, null);
|
||||
assertEquals("Invalid result", expected, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveCookieStringArgument() throws Exception {
|
||||
Cookie cookie = new Cookie("name", "foo");
|
||||
servletRequest.setCookies(cookie);
|
||||
|
||||
String result = (String) resolver.resolveArgument(cookieStringParameter, null, webRequest, null);
|
||||
assertEquals("Invalid result", cookie.getValue(), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveCookieDefaultValue() throws Exception {
|
||||
String result = (String) resolver.resolveArgument(cookieStringParameter, null, webRequest, null);
|
||||
assertEquals("Invalid result", "bar", result);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void notFound() throws Exception {
|
||||
String result = (String) resolver.resolveArgument(cookieParameter, null, webRequest, null);
|
||||
assertEquals("Invalid result", "bar", result);
|
||||
}
|
||||
|
||||
public void params(@CookieValue("name") Cookie cookie,
|
||||
@CookieValue(value = "name", defaultValue = "bar") String cookieString,
|
||||
String unsupported) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.method.annotation.support;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.lang.reflect.Method;
|
||||
import java.security.Principal;
|
||||
import java.util.Locale;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.mock.web.MockHttpSession;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.multipart.MultipartRequest;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.support.ServletRequestMethodArgumentResolver;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class ServletRequestMethodArgumentResolverTests {
|
||||
|
||||
private ServletRequestMethodArgumentResolver resolver;
|
||||
|
||||
private Method supportedParams;
|
||||
|
||||
private ServletWebRequest webRequest;
|
||||
|
||||
private MockHttpServletRequest servletRequest;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
resolver = new ServletRequestMethodArgumentResolver();
|
||||
supportedParams = getClass()
|
||||
.getMethod("supportedParams", ServletRequest.class, MultipartRequest.class, HttpSession.class,
|
||||
Principal.class, Locale.class, InputStream.class, Reader.class);
|
||||
servletRequest = new MockHttpServletRequest();
|
||||
webRequest = new ServletWebRequest(servletRequest, new MockHttpServletResponse());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void usesResponseArgument() {
|
||||
assertFalse("resolver uses response argument", resolver.usesResponseArgument(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void servletRequest() throws Exception {
|
||||
MethodParameter servletRequestParameter = new MethodParameter(supportedParams, 0);
|
||||
|
||||
assertTrue("ServletRequest not supported", resolver.supportsParameter(servletRequestParameter));
|
||||
|
||||
Object result = resolver.resolveArgument(servletRequestParameter, null, webRequest, null);
|
||||
assertSame("Invalid result", servletRequest, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void session() throws Exception {
|
||||
MockHttpSession session = new MockHttpSession();
|
||||
servletRequest.setSession(session);
|
||||
MethodParameter sessionParameter = new MethodParameter(supportedParams, 2);
|
||||
|
||||
assertTrue("Session not supported", resolver.supportsParameter(sessionParameter));
|
||||
|
||||
Object result = resolver.resolveArgument(sessionParameter, null, webRequest, null);
|
||||
assertSame("Invalid result", session, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void principal() throws Exception {
|
||||
Principal principal = new Principal() {
|
||||
public String getName() {
|
||||
return "Foo";
|
||||
}
|
||||
};
|
||||
servletRequest.setUserPrincipal(principal);
|
||||
MethodParameter principalParameter = new MethodParameter(supportedParams, 3);
|
||||
|
||||
assertTrue("Principal not supported", resolver.supportsParameter(principalParameter));
|
||||
|
||||
Object result = resolver.resolveArgument(principalParameter, null, webRequest, null);
|
||||
assertSame("Invalid result", principal, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void locale() throws Exception {
|
||||
Locale locale = Locale.ENGLISH;
|
||||
servletRequest.addPreferredLocale(locale);
|
||||
MethodParameter localeParameter = new MethodParameter(supportedParams, 4);
|
||||
|
||||
assertTrue("Locale not supported", resolver.supportsParameter(localeParameter));
|
||||
|
||||
Object result = resolver.resolveArgument(localeParameter, null, webRequest, null);
|
||||
assertSame("Invalid result", locale, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void inputStream() throws Exception {
|
||||
MethodParameter inputStreamParameter = new MethodParameter(supportedParams, 5);
|
||||
|
||||
assertTrue("InputStream not supported", resolver.supportsParameter(inputStreamParameter));
|
||||
|
||||
Object result = resolver.resolveArgument(inputStreamParameter, null, webRequest, null);
|
||||
assertSame("Invalid result", webRequest.getRequest().getInputStream(), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void reader() throws Exception {
|
||||
MethodParameter readerParameter = new MethodParameter(supportedParams, 6);
|
||||
|
||||
assertTrue("Reader not supported", resolver.supportsParameter(readerParameter));
|
||||
|
||||
Object result = resolver.resolveArgument(readerParameter, null, webRequest, null);
|
||||
assertSame("Invalid result", webRequest.getRequest().getReader(), result);
|
||||
}
|
||||
|
||||
public void supportedParams(ServletRequest p0,
|
||||
MultipartRequest p1,
|
||||
HttpSession p2,
|
||||
Principal p3,
|
||||
Locale p4,
|
||||
InputStream p5,
|
||||
Reader p9) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.method.annotation.support;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Method;
|
||||
import javax.servlet.ServletResponse;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.support.ServletResponseMethodArgumentResolver;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* @author Arjen Poutsma
|
||||
*/
|
||||
public class ServletResponseMethodArgumentResolverTests {
|
||||
|
||||
private ServletResponseMethodArgumentResolver resolver;
|
||||
|
||||
private Method supportedParams;
|
||||
|
||||
private ServletWebRequest webRequest;
|
||||
|
||||
private MockHttpServletResponse servletResponse;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
resolver = new ServletResponseMethodArgumentResolver();
|
||||
supportedParams =
|
||||
getClass().getMethod("supportedParams", ServletResponse.class, OutputStream.class, Writer.class);
|
||||
servletResponse = new MockHttpServletResponse();
|
||||
webRequest = new ServletWebRequest(new MockHttpServletRequest(), servletResponse);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void usesResponseArgument() {
|
||||
assertTrue("resolver uses response argument", resolver.usesResponseArgument(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void servletResponse() throws Exception {
|
||||
MethodParameter servletResponseParameter = new MethodParameter(supportedParams, 0);
|
||||
|
||||
assertTrue("ServletResponse not supported", resolver.supportsParameter(servletResponseParameter));
|
||||
|
||||
Object result = resolver.resolveArgument(servletResponseParameter, null, webRequest, null);
|
||||
assertSame("Invalid result", servletResponse, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStream() throws Exception {
|
||||
MethodParameter outputStreamParameter = new MethodParameter(supportedParams, 1);
|
||||
|
||||
assertTrue("OutputStream not supported", resolver.supportsParameter(outputStreamParameter));
|
||||
|
||||
Object result = resolver.resolveArgument(outputStreamParameter, null, webRequest, null);
|
||||
assertSame("Invalid result", servletResponse.getOutputStream(), result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writer() throws Exception {
|
||||
MethodParameter writerParameter = new MethodParameter(supportedParams, 2);
|
||||
|
||||
assertTrue("Writer not supported", resolver.supportsParameter(writerParameter));
|
||||
|
||||
Object result = resolver.resolveArgument(writerParameter, null, webRequest, null);
|
||||
assertSame("Invalid result", servletResponse.getWriter(), result);
|
||||
}
|
||||
|
||||
public void supportedParams(ServletResponse p0, OutputStream p1, Writer p2) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright 2002-2011 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.method.annotation.support;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.ui.ExtendedModelMap;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||
import org.springframework.web.servlet.View;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.support.DefaultMethodReturnValueHandler;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.support.ViewMethodReturnValueHandler;
|
||||
import org.springframework.web.servlet.view.InternalResourceView;
|
||||
|
||||
/**
|
||||
* Test fixture for {@link DefaultMethodReturnValueHandler} unit tests.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class ViewMethodReturnValueHandlerTests {
|
||||
|
||||
private ViewMethodReturnValueHandler handler;
|
||||
|
||||
private ServletWebRequest webRequest;
|
||||
|
||||
private ModelAndViewContainer<View> mavContainer;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.handler = new ViewMethodReturnValueHandler();
|
||||
this.mavContainer = new ModelAndViewContainer<View>(new ExtendedModelMap());
|
||||
this.webRequest = new ServletWebRequest(new MockHttpServletRequest());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportsReturnType() throws Exception {
|
||||
assertTrue(handler.supportsReturnType(createMethodParam("view")));
|
||||
assertTrue(handler.supportsReturnType(createMethodParam("viewName")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnView() throws Exception {
|
||||
InternalResourceView view = new InternalResourceView("testView");
|
||||
handler.handleReturnValue(view, createMethodParam("view"), mavContainer, webRequest);
|
||||
assertSame(view, mavContainer.getView());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnViewName() throws Exception {
|
||||
handler.handleReturnValue("testView", createMethodParam("viewName"), mavContainer, webRequest);
|
||||
assertEquals("testView", mavContainer.getViewName());
|
||||
}
|
||||
|
||||
private MethodParameter createMethodParam(String methodName) throws Exception {
|
||||
Method method = getClass().getDeclaredMethod(methodName);
|
||||
return new MethodParameter(method, -1);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private View view() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private String viewName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user