SPR-8214 review unit tests

git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@4227 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
Rossen Stoyanchev 2011-04-15 18:42:58 +00:00
parent 6f8fa24e59
commit aae28ee298
42 changed files with 1189 additions and 1083 deletions

View File

@ -121,13 +121,11 @@ import org.springframework.web.util.WebUtils;
public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAdapter implements BeanFactoryAware, public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAdapter implements BeanFactoryAware,
InitializingBean { InitializingBean {
private final List<HandlerMethodArgumentResolver> customArgumentResolvers = private List<HandlerMethodArgumentResolver> customArgumentResolvers;
new ArrayList<HandlerMethodArgumentResolver>();
private final List<HandlerMethodReturnValueHandler> customReturnValueHandlers = private List<HandlerMethodReturnValueHandler> customReturnValueHandlers;
new ArrayList<HandlerMethodReturnValueHandler>();
private final List<ModelAndViewResolver> modelAndViewResolvers = new ArrayList<ModelAndViewResolver>(); private List<ModelAndViewResolver> modelAndViewResolvers;
private List<HttpMessageConverter<?>> messageConverters; private List<HttpMessageConverter<?>> messageConverters;
@ -179,9 +177,7 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
* or preferably converted to a {@link HandlerMethodArgumentResolver} instead. * or preferably converted to a {@link HandlerMethodArgumentResolver} instead.
*/ */
public void setCustomArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { public void setCustomArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
if (argumentResolvers != null) { this.customArgumentResolvers = argumentResolvers;
this.customArgumentResolvers.addAll(argumentResolvers);
}
} }
/** /**
@ -193,7 +189,7 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
public void setArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { public void setArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
if (argumentResolvers != null) { if (argumentResolvers != null) {
this.argumentResolvers = new HandlerMethodArgumentResolverComposite(); this.argumentResolvers = new HandlerMethodArgumentResolverComposite();
registerArgumentResolvers(argumentResolvers); this.argumentResolvers.addResolvers(argumentResolvers);
} }
} }
@ -206,7 +202,7 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
public void setInitBinderArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { public void setInitBinderArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
if (argumentResolvers != null) { if (argumentResolvers != null) {
this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite(); this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite();
registerInitBinderArgumentResolvers(argumentResolvers); this.initBinderArgumentResolvers.addResolvers(argumentResolvers);
} }
} }
@ -217,9 +213,7 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
* @param returnValueHandlers custom return value handlers for {@link RequestMapping} methods * @param returnValueHandlers custom return value handlers for {@link RequestMapping} methods
*/ */
public void setCustomReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) { public void setCustomReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
if (returnValueHandlers != null) { this.customReturnValueHandlers = returnValueHandlers;
this.customReturnValueHandlers.addAll(returnValueHandlers);
}
} }
/** /**
@ -231,7 +225,7 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
public void setReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) { public void setReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
if (returnValueHandlers != null) { if (returnValueHandlers != null) {
this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite(); this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite();
registerReturnValueHandlers(returnValueHandlers); this.returnValueHandlers.addHandlers(returnValueHandlers);
} }
} }
@ -244,9 +238,7 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
* {@link HandlerMethodReturnValueHandler} and {@link #setCustomReturnValueHandlers(List)} instead. * {@link HandlerMethodReturnValueHandler} and {@link #setCustomReturnValueHandlers(List)} instead.
*/ */
public void setModelAndViewResolvers(List<ModelAndViewResolver> modelAndViewResolvers) { public void setModelAndViewResolvers(List<ModelAndViewResolver> modelAndViewResolvers) {
if (modelAndViewResolvers != null) { this.modelAndViewResolvers = modelAndViewResolvers;
this.modelAndViewResolvers.addAll(modelAndViewResolvers);
}
} }
/** /**
@ -334,36 +326,20 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
if (argumentResolvers == null) { if (argumentResolvers == null) {
argumentResolvers = new HandlerMethodArgumentResolverComposite(); argumentResolvers = new HandlerMethodArgumentResolverComposite();
registerArgumentResolvers(customArgumentResolvers); argumentResolvers.addResolvers(customArgumentResolvers);
registerArgumentResolvers(getDefaultArgumentResolvers(messageConverters, beanFactory)); argumentResolvers.addResolvers(getDefaultArgumentResolvers(messageConverters, beanFactory));
} }
if (returnValueHandlers == null) { if (returnValueHandlers == null) {
returnValueHandlers = new HandlerMethodReturnValueHandlerComposite(); returnValueHandlers = new HandlerMethodReturnValueHandlerComposite();
registerReturnValueHandlers(customReturnValueHandlers); returnValueHandlers.addHandlers(customReturnValueHandlers);
registerReturnValueHandlers(getDefaultReturnValueHandlers(messageConverters, modelAndViewResolvers)); returnValueHandlers.addHandlers(getDefaultReturnValueHandlers(messageConverters, modelAndViewResolvers));
} }
if (initBinderArgumentResolvers == null) { if (initBinderArgumentResolvers == null) {
initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite(); initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite();
registerInitBinderArgumentResolvers(customArgumentResolvers); initBinderArgumentResolvers.addResolvers(customArgumentResolvers);
registerInitBinderArgumentResolvers(getDefaultInitBinderArgumentResolvers(beanFactory)); initBinderArgumentResolvers.addResolvers(getDefaultInitBinderArgumentResolvers(beanFactory));
}
}
private void registerArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
for (HandlerMethodArgumentResolver resolver : argumentResolvers) {
this.argumentResolvers.registerArgumentResolver(resolver);
}
}
private void registerInitBinderArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
for (HandlerMethodArgumentResolver resolver : argumentResolvers) {
this.initBinderArgumentResolvers.registerArgumentResolver(resolver);
}
}
private void registerReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
for (HandlerMethodReturnValueHandler handler : returnValueHandlers) {
this.returnValueHandlers.registerReturnValueHandler(handler);
} }
} }
@ -372,6 +348,7 @@ public class RequestMappingHandlerMethodAdapter extends AbstractHandlerMethodAda
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>(); List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>();
// Annotation-based resolvers
resolvers.add(new RequestParamMethodArgumentResolver(beanFactory, false)); resolvers.add(new RequestParamMethodArgumentResolver(beanFactory, false));
resolvers.add(new RequestParamMapMethodArgumentResolver()); resolvers.add(new RequestParamMapMethodArgumentResolver());
resolvers.add(new PathVariableMethodArgumentResolver()); resolvers.add(new PathVariableMethodArgumentResolver());

View File

@ -82,11 +82,9 @@ import org.springframework.web.servlet.mvc.method.annotation.support.ViewMethodR
public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandlerMethodExceptionResolver implements public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandlerMethodExceptionResolver implements
InitializingBean { InitializingBean {
private final List<HandlerMethodArgumentResolver> customArgumentResolvers = private List<HandlerMethodArgumentResolver> customArgumentResolvers;
new ArrayList<HandlerMethodArgumentResolver>();
private final List<HandlerMethodReturnValueHandler> customReturnValueHandlers = private List<HandlerMethodReturnValueHandler> customReturnValueHandlers;
new ArrayList<HandlerMethodReturnValueHandler>();
private List<HttpMessageConverter<?>> messageConverters; private List<HttpMessageConverter<?>> messageConverters;
@ -119,9 +117,7 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle
* or preferably converted to a {@link HandlerMethodArgumentResolver} instead. * or preferably converted to a {@link HandlerMethodArgumentResolver} instead.
*/ */
public void setCustomArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { public void setCustomArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
if (argumentResolvers != null) { this.customArgumentResolvers= argumentResolvers;
this.customArgumentResolvers.addAll(argumentResolvers);
}
} }
/** /**
@ -133,7 +129,7 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle
public void setArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { public void setArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
if (argumentResolvers != null) { if (argumentResolvers != null) {
this.argumentResolvers = new HandlerMethodArgumentResolverComposite(); this.argumentResolvers = new HandlerMethodArgumentResolverComposite();
registerArgumentResolvers(argumentResolvers); this.argumentResolvers.addResolvers(argumentResolvers);
} }
} }
@ -144,9 +140,7 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle
* @param returnValueHandlers custom return value handlers for {@link ExceptionHandler} methods * @param returnValueHandlers custom return value handlers for {@link ExceptionHandler} methods
*/ */
public void setCustomReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) { public void setCustomReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
if (returnValueHandlers != null) { this.customReturnValueHandlers = returnValueHandlers;
this.customReturnValueHandlers.addAll(returnValueHandlers);
}
} }
/** /**
@ -158,7 +152,7 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle
public void setReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) { public void setReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
if (returnValueHandlers != null) { if (returnValueHandlers != null) {
this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite(); this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite();
registerReturnValueHandlers(returnValueHandlers); this.returnValueHandlers.addHandlers(returnValueHandlers);
} }
} }
@ -173,25 +167,13 @@ public class RequestMappingHandlerMethodExceptionResolver extends AbstractHandle
public void afterPropertiesSet() throws Exception { public void afterPropertiesSet() throws Exception {
if (argumentResolvers == null) { if (argumentResolvers == null) {
argumentResolvers = new HandlerMethodArgumentResolverComposite(); argumentResolvers = new HandlerMethodArgumentResolverComposite();
registerArgumentResolvers(customArgumentResolvers); argumentResolvers.addResolvers(customArgumentResolvers);
registerArgumentResolvers(getDefaultArgumentResolvers()); argumentResolvers.addResolvers(getDefaultArgumentResolvers());
} }
if (returnValueHandlers == null) { if (returnValueHandlers == null) {
returnValueHandlers = new HandlerMethodReturnValueHandlerComposite(); returnValueHandlers = new HandlerMethodReturnValueHandlerComposite();
registerReturnValueHandlers(customReturnValueHandlers); returnValueHandlers.addHandlers(customReturnValueHandlers);
registerReturnValueHandlers(getDefaultReturnValueHandlers(messageConverters)); returnValueHandlers.addHandlers(getDefaultReturnValueHandlers(messageConverters));
}
}
private void registerArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
for (HandlerMethodArgumentResolver resolver : argumentResolvers) {
this.argumentResolvers.registerArgumentResolver(resolver);
}
}
private void registerReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
for (HandlerMethodReturnValueHandler handler : returnValueHandlers) {
this.returnValueHandlers.registerReturnValueHandler(handler);
} }
} }

View File

@ -52,7 +52,7 @@ import org.springframework.web.servlet.mvc.annotation.ModelAndViewResolver;
*/ */
public class DefaultMethodReturnValueHandler implements HandlerMethodReturnValueHandler { public class DefaultMethodReturnValueHandler implements HandlerMethodReturnValueHandler {
private final List<ModelAndViewResolver> modelAndViewResolvers = new ArrayList<ModelAndViewResolver>(); private final List<ModelAndViewResolver> mavResolvers;
/** /**
* Create a {@link DefaultMethodReturnValueHandler} instance without {@link ModelAndViewResolver}s. * Create a {@link DefaultMethodReturnValueHandler} instance without {@link ModelAndViewResolver}s.
@ -64,10 +64,8 @@ public class DefaultMethodReturnValueHandler implements HandlerMethodReturnValue
/** /**
* Create a {@link DefaultMethodReturnValueHandler} with a list of {@link ModelAndViewResolver}s. * Create a {@link DefaultMethodReturnValueHandler} with a list of {@link ModelAndViewResolver}s.
*/ */
public DefaultMethodReturnValueHandler(List<ModelAndViewResolver> modelAndViewResolvers) { public DefaultMethodReturnValueHandler(List<ModelAndViewResolver> mavResolvers) {
if (modelAndViewResolvers != null) { this.mavResolvers = mavResolvers;
this.modelAndViewResolvers.addAll(modelAndViewResolvers);
}
} }
public boolean supportsReturnType(MethodParameter returnType) { public boolean supportsReturnType(MethodParameter returnType) {
@ -77,13 +75,14 @@ public class DefaultMethodReturnValueHandler implements HandlerMethodReturnValue
public void handleReturnValue(Object returnValue, public void handleReturnValue(Object returnValue,
MethodParameter returnType, MethodParameter returnType,
ModelAndViewContainer mavContainer, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest) throws Exception { NativeWebRequest request) throws Exception {
for (ModelAndViewResolver resolver : modelAndViewResolvers) { if (mavResolvers != null) {
for (ModelAndViewResolver resolver : mavResolvers) {
Class<?> handlerType = returnType.getDeclaringClass(); Class<?> handlerType = returnType.getDeclaringClass();
Method method = returnType.getMethod(); Method method = returnType.getMethod();
ExtendedModelMap extModel = (ExtendedModelMap) mavContainer.getModel(); ExtendedModelMap model = (ExtendedModelMap) mavContainer.getModel();
ModelAndView mav = resolver.resolveModelAndView(method, handlerType, returnValue, extModel, webRequest); ModelAndView mav = resolver.resolveModelAndView(method, handlerType, returnValue, model, request);
if (mav != ModelAndViewResolver.UNRESOLVED) { if (mav != ModelAndViewResolver.UNRESOLVED) {
mavContainer.setView(mav.getView()); mavContainer.setView(mav.getView());
mavContainer.setViewName(mav.getViewName()); mavContainer.setViewName(mav.getViewName());
@ -91,6 +90,7 @@ public class DefaultMethodReturnValueHandler implements HandlerMethodReturnValue
return; return;
} }
} }
}
if (returnValue == null) { if (returnValue == null) {
return; return;

View File

@ -36,9 +36,7 @@ import org.springframework.validation.MessageCodesResolver;
import org.springframework.validation.Validator; import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer; import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
import org.springframework.web.bind.support.WebArgumentResolver;
import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodAdapter; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodAdapter;
import org.springframework.web.servlet.mvc.method.annotation.support.ServletWebArgumentResolverAdapter; import org.springframework.web.servlet.mvc.method.annotation.support.ServletWebArgumentResolverAdapter;

View File

@ -68,7 +68,7 @@ import org.springframework.web.servlet.mvc.method.annotation.support.DefaultMeth
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
@RunWith(Parameterized.class) @RunWith(Parameterized.class)
public class ControllerMethodAnnotationDetectionTests { public class HandlerMethodAdapterAnnotationDetectionTests {
@Parameters @Parameters
public static Collection<Object[]> handlerTypes() { public static Collection<Object[]> handlerTypes() {
@ -87,7 +87,7 @@ public class ControllerMethodAnnotationDetectionTests {
private boolean useAutoProxy; private boolean useAutoProxy;
public ControllerMethodAnnotationDetectionTests(Object handler, boolean useAutoProxy) { public HandlerMethodAdapterAnnotationDetectionTests(Object handler, boolean useAutoProxy) {
this.handler = handler; this.handler = handler;
this.useAutoProxy = useAutoProxy; this.useAutoProxy = useAutoProxy;
} }
@ -117,11 +117,11 @@ public class ControllerMethodAnnotationDetectionTests {
handler = getProxyBean(handler); handler = getProxyBean(handler);
} }
HandlerMethodArgumentResolverComposite argResolvers = new HandlerMethodArgumentResolverComposite(); HandlerMethodArgumentResolverComposite argResolvers = new HandlerMethodArgumentResolverComposite();
argResolvers.registerArgumentResolver(new ModelAttributeMethodProcessor(false)); argResolvers.addResolver(new ModelAttributeMethodProcessor(false));
HandlerMethodReturnValueHandlerComposite handlers = new HandlerMethodReturnValueHandlerComposite(); HandlerMethodReturnValueHandlerComposite handlers = new HandlerMethodReturnValueHandlerComposite();
handlers.registerReturnValueHandler(new ModelAttributeMethodProcessor(false)); handlers.addHandler(new ModelAttributeMethodProcessor(false));
handlers.registerReturnValueHandler(new DefaultMethodReturnValueHandler(null)); handlers.addHandler(new DefaultMethodReturnValueHandler(null));
Class<?> handlerType = ClassUtils.getUserClass(handler.getClass()); Class<?> handlerType = ClassUtils.getUserClass(handler.getClass());
Set<Method> methods = HandlerMethodSelector.selectMethods(handlerType, REQUEST_MAPPING_METHODS); Set<Method> methods = HandlerMethodSelector.selectMethods(handlerType, REQUEST_MAPPING_METHODS);

View File

@ -21,8 +21,6 @@ import static org.junit.Assert.assertNotNull;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import javax.servlet.http.HttpServletRequest;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.Parameterized; import org.junit.runners.Parameterized;
@ -38,7 +36,6 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.support.GenericWebApplicationContext; import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.method.HandlerMethod; 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 * Test various scenarios for detecting handler methods depending on where @RequestMapping annotations
@ -55,7 +52,7 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
@RunWith(Parameterized.class) @RunWith(Parameterized.class)
public class RequestMappingHandlerMethodDetectionTests { public class HandlerMethodMappingAnnotationDetectionTests {
@Parameters @Parameters
public static Collection<Object[]> handlerTypes() { public static Collection<Object[]> handlerTypes() {
@ -74,7 +71,7 @@ public class RequestMappingHandlerMethodDetectionTests {
private boolean useAutoProxy; private boolean useAutoProxy;
public RequestMappingHandlerMethodDetectionTests(Object handler, boolean useAutoProxy) { public HandlerMethodMappingAnnotationDetectionTests(Object handler, boolean useAutoProxy) {
this.handler = handler; this.handler = handler;
this.useAutoProxy = useAutoProxy; this.useAutoProxy = useAutoProxy;
} }
@ -83,13 +80,13 @@ public class RequestMappingHandlerMethodDetectionTests {
public void detectAndMapHandlerMethod() throws Exception { public void detectAndMapHandlerMethod() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/type/handle"); MockHttpServletRequest request = new MockHttpServletRequest("GET", "/type/handle");
TestRequestMappingHandlerMethodMapping mapping = createHandlerMapping(handler.getClass(), useAutoProxy); RequestMappingHandlerMethodMapping mapping = createHandlerMapping(handler.getClass(), useAutoProxy);
HandlerMethod handlerMethod = mapping.getHandlerInternal(request); HandlerMethod handlerMethod = (HandlerMethod) mapping.getHandler(request).getHandler();
assertNotNull("Failed to detect and map @RequestMapping handler method", handlerMethod); assertNotNull("Failed to detect and map @RequestMapping handler method", handlerMethod);
} }
private TestRequestMappingHandlerMethodMapping createHandlerMapping(Class<?> controllerType, boolean useAutoProxy) { private RequestMappingHandlerMethodMapping createHandlerMapping(Class<?> controllerType, boolean useAutoProxy) {
GenericWebApplicationContext wac = new GenericWebApplicationContext(); GenericWebApplicationContext wac = new GenericWebApplicationContext();
wac.registerBeanDefinition("controller", new RootBeanDefinition(controllerType)); wac.registerBeanDefinition("controller", new RootBeanDefinition(controllerType));
if (useAutoProxy) { if (useAutoProxy) {
@ -99,18 +96,11 @@ public class RequestMappingHandlerMethodDetectionTests {
wac.getBeanFactory().registerSingleton("advsr", new DefaultPointcutAdvisor(new SimpleTraceInterceptor())); wac.getBeanFactory().registerSingleton("advsr", new DefaultPointcutAdvisor(new SimpleTraceInterceptor()));
} }
TestRequestMappingHandlerMethodMapping mapping = new TestRequestMappingHandlerMethodMapping(); RequestMappingHandlerMethodMapping mapping = new RequestMappingHandlerMethodMapping();
mapping.setApplicationContext(wac); mapping.setApplicationContext(wac);
return mapping; return mapping;
} }
public static class TestRequestMappingHandlerMethodMapping extends RequestMappingHandlerMethodMapping {
public HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
return super.getHandlerInternal(request);
}
}
/* Annotation on interface method */ /* Annotation on interface method */
@Controller @Controller

View File

@ -32,6 +32,8 @@ import static java.util.Arrays.*;
import static org.junit.Assert.*; import static org.junit.Assert.*;
/** /**
* Test fixture with {@link RequestMappingHandlerMethodMapping} testing its {@link RequestKey} comparator.
*
* @author Arjen Poutsma * @author Arjen Poutsma
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
@ -143,4 +145,5 @@ public class RequestKeyComparatorTests {
assertTrue(comparator.compare(html, xml) > 0); assertTrue(comparator.compare(html, xml) > 0);
assertTrue(comparator.compare(xml, html) < 0); assertTrue(comparator.compare(xml, html) < 0);
} }
} }

View File

@ -31,6 +31,8 @@ import static org.junit.Assert.*;
import static org.springframework.web.bind.annotation.RequestMethod.*; import static org.springframework.web.bind.annotation.RequestMethod.*;
/** /**
* Test fixture for {@link RequestKey} tests.
*
* @author Arjen Poutsma * @author Arjen Poutsma
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */

View File

@ -52,7 +52,6 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult; import org.springframework.validation.BindingResult;
@ -83,24 +82,23 @@ import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.method.annotation.support.ServletWebArgumentResolverAdapter; import org.springframework.web.servlet.mvc.method.annotation.support.ServletWebArgumentResolverAdapter;
/** /**
* A test fixture for higher-level {@link RequestMappingHandlerMethodAdapter} tests. * Serves as a sandbox to invoke all types of controller methods using all features except for the kitchen sink.
* Once a problem has been debugged and understood, tests demonstrating the issue are preferably added to the
* appropriate, more fine-grained test fixture.
* *
* <p>The aim here is not to test {@link RequestMappingHandlerMethodAdapter} itself nor to exercise * <p>If you wish to add high-level tests, consider the following other "integration"-style tests:
* 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> * <ul>
* <li>{@link RequestMappingHandlerMethodDetectionTests} * <li>{@link HandlerMethodAdapterAnnotationDetectionTests}
* <li>{@link ControllerMethodAnnotationDetectionTests} * <li>{@link HandlerMethodMappingAnnotationDetectionTests}
* <li>{@link ServletHandlerMethodTests}
* </ul> * </ul>
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
public class RequestMappingHandlerMethodAdapterIntegrationTests { public class RequestMappingHandlerMethodAdapterIntegrationTests {
private final Object handler = new Handler();
private RequestMappingHandlerMethodAdapter handlerAdapter; private RequestMappingHandlerMethodAdapter handlerAdapter;
private MockHttpServletRequest request; private MockHttpServletRequest request;
@ -115,19 +113,18 @@ public class RequestMappingHandlerMethodAdapterIntegrationTests {
List<HandlerMethodArgumentResolver> customResolvers = new ArrayList<HandlerMethodArgumentResolver>(); List<HandlerMethodArgumentResolver> customResolvers = new ArrayList<HandlerMethodArgumentResolver>();
customResolvers.add(new ServletWebArgumentResolverAdapter(new ColorArgumentResolver())); customResolvers.add(new ServletWebArgumentResolverAdapter(new ColorArgumentResolver()));
this.handlerAdapter = new RequestMappingHandlerMethodAdapter();
this.handlerAdapter.setWebBindingInitializer(bindingInitializer);
this.handlerAdapter.setCustomArgumentResolvers(customResolvers);
GenericWebApplicationContext context = new GenericWebApplicationContext(); GenericWebApplicationContext context = new GenericWebApplicationContext();
context.refresh(); context.refresh();
this.handlerAdapter.setApplicationContext(context); handlerAdapter = new RequestMappingHandlerMethodAdapter();
this.handlerAdapter.setBeanFactory(context.getBeanFactory()); handlerAdapter.setWebBindingInitializer(bindingInitializer);
this.handlerAdapter.afterPropertiesSet(); handlerAdapter.setCustomArgumentResolvers(customResolvers);
handlerAdapter.setApplicationContext(context);
handlerAdapter.setBeanFactory(context.getBeanFactory());
handlerAdapter.afterPropertiesSet();
this.request = new MockHttpServletRequest(); request = new MockHttpServletRequest();
this.response = new MockHttpServletResponse(); response = new MockHttpServletResponse();
// Expose request to the current thread (for SpEL expressions) // Expose request to the current thread (for SpEL expressions)
RequestContextHolder.setRequestAttributes(new ServletWebRequest(request)); RequestContextHolder.setRequestAttributes(new ServletWebRequest(request));
@ -140,36 +137,36 @@ public class RequestMappingHandlerMethodAdapterIntegrationTests {
@Test @Test
public void handleMvc() throws Exception { public void handleMvc() throws Exception {
Class<?>[] paramTypes = new Class<?>[] { int.class, String.class, String.class, String.class, Map.class,
Class<?>[] parameterTypes = 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, Date.class, Map.class, String.class, String.class, TestBean.class, Errors.class, TestBean.class,
Color.class, HttpServletRequest.class, HttpServletResponse.class, User.class, OtherUser.class, Color.class, HttpServletRequest.class, HttpServletResponse.class, User.class, OtherUser.class,
Model.class }; Model.class };
/* URI template vars (see RequestMappingHandlerMethodMapping) */ String datePattern = "yyyy.MM.dd";
String formattedDate = "2011.03.16";
Date date = new GregorianCalendar(2011, Calendar.MARCH, 16).getTime();
request.addHeader("Content-Type", "text/plain; charset=utf-8");
request.addHeader("header", "headerValue");
request.addHeader("anotherHeader", "anotherHeaderValue");
request.addParameter("datePattern", datePattern);
request.addParameter("dateParam", formattedDate);
request.addParameter("paramByConvention", "paramByConventionValue");
request.addParameter("age", "25");
request.setCookies(new Cookie("cookie", "99"));
request.setContent("Hello World".getBytes("UTF-8"));
request.setUserPrincipal(new User());
request.setContextPath("/contextPath");
System.setProperty("systemHeader", "systemHeaderValue");
/* Set up path variables as RequestMappingHandlerMethodMapping would... */
Map<String, String> uriTemplateVars = new HashMap<String, String>(); Map<String, String> uriTemplateVars = new HashMap<String, String>();
uriTemplateVars.put("pathvar", "pathvarValue"); uriTemplateVars.put("pathvar", "pathvarValue");
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars); request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars);
Date date = new GregorianCalendar(2011, Calendar.MARCH, 16).getTime(); HandlerMethod handlerMethod = handlerMethod("handleMvc", parameterTypes);
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); ModelAndView mav = handlerAdapter.handle(request, response, handlerMethod);
ModelMap model = mav.getModelMap(); ModelMap model = mav.getModelMap();
@ -215,12 +212,13 @@ public class RequestMappingHandlerMethodAdapterIntegrationTests {
@Test @Test
public void handleRequestBody() throws Exception { public void handleRequestBody() throws Exception {
Class<?>[] paramTypes = new Class<?>[] { byte[].class };
Class<?>[] parameterTypes = new Class<?>[] { byte[].class };
request.addHeader("Content-Type", "text/plain; charset=utf-8"); request.addHeader("Content-Type", "text/plain; charset=utf-8");
request.setContent("Hello Server".getBytes("UTF-8")); request.setContent("Hello Server".getBytes("UTF-8"));
HandlerMethod handlerMethod = handlerMethod(new RequestMappingHandler(), "handleRequestBody", paramTypes); HandlerMethod handlerMethod = handlerMethod("handleRequestBody", parameterTypes);
ModelAndView mav = handlerAdapter.handle(request, response, handlerMethod); ModelAndView mav = handlerAdapter.handle(request, response, handlerMethod);
@ -231,12 +229,13 @@ public class RequestMappingHandlerMethodAdapterIntegrationTests {
@Test @Test
public void handleHttpEntity() throws Exception { public void handleHttpEntity() throws Exception {
Class<?>[] paramTypes = new Class<?>[] { HttpEntity.class };
Class<?>[] parameterTypes = new Class<?>[] { HttpEntity.class };
request.addHeader("Content-Type", "text/plain; charset=utf-8"); request.addHeader("Content-Type", "text/plain; charset=utf-8");
request.setContent("Hello Server".getBytes("UTF-8")); request.setContent("Hello Server".getBytes("UTF-8"));
HandlerMethod handlerMethod = handlerMethod(new RequestMappingHandler(), "handleHttpEntity", paramTypes); HandlerMethod handlerMethod = handlerMethod("handleHttpEntity", parameterTypes);
ModelAndView mav = handlerAdapter.handle(request, response, handlerMethod); ModelAndView mav = handlerAdapter.handle(request, response, handlerMethod);
@ -246,22 +245,21 @@ public class RequestMappingHandlerMethodAdapterIntegrationTests {
assertEquals("headerValue", response.getHeader("header")); assertEquals("headerValue", response.getHeader("header"));
} }
private HandlerMethod handlerMethod(Object handler, String methodName, Class<?>... paramTypes) throws Exception { private HandlerMethod handlerMethod(String methodName, Class<?>... paramTypes) throws Exception {
Method method = handler.getClass().getDeclaredMethod(methodName, paramTypes); Method method = handler.getClass().getDeclaredMethod(methodName, paramTypes);
return new InvocableHandlerMethod(handler, method); return new InvocableHandlerMethod(handler, method);
} }
@SessionAttributes(types=TestBean.class)
private static class RequestMappingHandler {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@SessionAttributes(types=TestBean.class)
private static class Handler {
@InitBinder("dateParam") @InitBinder("dateParam")
public void initBinder(WebDataBinder dataBinder, @RequestParam("datePattern") String datePattern) { public void initBinder(WebDataBinder dataBinder, @RequestParam("datePattern") String datePattern) {
SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern); SimpleDateFormat dateFormat = new SimpleDateFormat(datePattern);
dataBinder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false)); dataBinder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
} }
@SuppressWarnings("unused")
@ModelAttribute @ModelAttribute
public void model(Model model) { public void model(Model model) {
TestBean modelAttr = new TestBean(); TestBean modelAttr = new TestBean();
@ -275,7 +273,6 @@ public class RequestMappingHandlerMethodAdapterIntegrationTests {
model.addAttribute(new OtherUser()); model.addAttribute(new OtherUser());
} }
@SuppressWarnings("unused")
public String handleMvc( public String handleMvc(
@CookieValue("cookie") int cookie, @CookieValue("cookie") int cookie,
@PathVariable("pathvar") String pathvar, @PathVariable("pathvar") String pathvar,
@ -308,7 +305,6 @@ public class RequestMappingHandlerMethodAdapterIntegrationTests {
return "viewName"; return "viewName";
} }
@SuppressWarnings("unused")
@ResponseStatus(value=HttpStatus.ACCEPTED) @ResponseStatus(value=HttpStatus.ACCEPTED)
@ResponseBody @ResponseBody
public String handleRequestBody(@RequestBody byte[] bytes) throws Exception { public String handleRequestBody(@RequestBody byte[] bytes) throws Exception {
@ -316,7 +312,6 @@ public class RequestMappingHandlerMethodAdapterIntegrationTests {
return "Handled requestBody=[" + requestBody + "]"; return "Handled requestBody=[" + requestBody + "]";
} }
@SuppressWarnings("unused")
public ResponseEntity<String> handleHttpEntity(HttpEntity<byte[]> httpEntity) throws Exception { public ResponseEntity<String> handleHttpEntity(HttpEntity<byte[]> httpEntity) throws Exception {
HttpHeaders responseHeaders = new HttpHeaders(); HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("header", "headerValue"); responseHeaders.set("header", "headerValue");
@ -352,4 +347,5 @@ public class RequestMappingHandlerMethodAdapterIntegrationTests {
return "other user"; return "other user";
} }
} }
} }

View File

@ -25,19 +25,20 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.SessionAttributes; import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.context.support.GenericWebApplicationContext; import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.support.InvocableHandlerMethod; import org.springframework.web.method.support.InvocableHandlerMethod;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodAdapter;
/** /**
* Test fixture for {@link RequestMappingHandlerMethodAdapter} unit tests. * Fine-grained {@link RequestMappingHandlerMethodAdapter} unit tests.
* *
* The tests in this class focus on {@link RequestMappingHandlerMethodAdapter} functionality exclusively. * <p>For higher-level adapter tests see:
* Also see {@link RequestMappingHandlerMethodAdapterIntegrationTests} for higher-level tests invoking * <ul>
* {@link Controller @Controller} methods. * <li>{@link ServletHandlerMethodTests}
* <li>{@link RequestMappingHandlerMethodAdapterIntegrationTests}
* <li>{@link HandlerMethodAdapterAnnotationDetectionTests}
* </ul>
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
@ -94,4 +95,5 @@ public class RequestMappingHandlerMethodAdapterTests {
public void handle() { public void handle() {
} }
} }
} }

View File

@ -46,7 +46,7 @@ import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodExceptionResolver; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodExceptionResolver;
/** /**
* Test fixture for {@link RequestMappingHandlerMethodExceptionResolver} unit tests. * Test fixture with {@link RequestMappingHandlerMethodExceptionResolver}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
* @author Arjen Poutsma * @author Arjen Poutsma

View File

@ -16,13 +16,19 @@
package org.springframework.web.servlet.mvc.method.annotation; 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.Arrays;
import java.util.Map; import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.junit.Before; import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.springframework.context.support.StaticApplicationContext; import org.springframework.context.support.StaticApplicationContext;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
@ -36,50 +42,67 @@ import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import org.springframework.web.servlet.handler.MappedInterceptor; import org.springframework.web.servlet.handler.MappedInterceptor;
import static org.junit.Assert.*;
/** /**
* Test fixture with {@link RequestMappingHandlerMethodMapping}.
*
* @author Arjen Poutsma * @author Arjen Poutsma
* @author Rossen Stoyanchev
*/ */
public class RequestMappingHandlerMethodMappingTests { public class RequestMappingHandlerMethodMappingTests {
private MyRequestMappingHandlerMethodMapping mapping; private RequestMappingHandlerMethodMapping mapping;
private MyHandler handler; private Handler handler;
private HandlerMethod fooMethod; private HandlerMethod fooMethod;
private HandlerMethod fooParamMethod;
private HandlerMethod barMethod; private HandlerMethod barMethod;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
handler = new MyHandler(); handler = new Handler();
fooMethod = new HandlerMethod(handler, "foo"); fooMethod = new HandlerMethod(handler, "foo");
fooParamMethod = new HandlerMethod(handler, "fooParam");
barMethod = new HandlerMethod(handler, "bar"); barMethod = new HandlerMethod(handler, "bar");
StaticApplicationContext context = new StaticApplicationContext(); StaticApplicationContext context = new StaticApplicationContext();
context.registerSingleton("handler", handler.getClass()); context.registerSingleton("handler", handler.getClass());
mapping = new MyRequestMappingHandlerMethodMapping(); mapping = new RequestMappingHandlerMethodMapping();
mapping.setApplicationContext(context); mapping.setApplicationContext(context);
} }
@Test @Test
public void directMatch() throws Exception { public void directMatch() throws Exception {
HandlerMethod result = mapping.getHandlerInternal(new MockHttpServletRequest("GET", "/foo")); MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
assertEquals(fooMethod.getMethod(), result.getMethod()); HandlerMethod hm = (HandlerMethod) mapping.getHandler(request).getHandler();
assertEquals(fooMethod.getMethod(), hm.getMethod());
} }
@Test @Test
public void globMatch() throws Exception { public void globMatch() throws Exception {
HandlerMethod result = mapping.getHandlerInternal(new MockHttpServletRequest("GET", "/bar")); MockHttpServletRequest request = new MockHttpServletRequest("GET", "/bar");
assertEquals(barMethod.getMethod(), result.getMethod()); HandlerMethod hm = (HandlerMethod) mapping.getHandler(request).getHandler();
assertEquals(barMethod.getMethod(), hm.getMethod());
}
// TODO: SPR-8247
@Ignore
@Test
public void bestMatch() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo");
request.setParameter("p", "anything");
HandlerMethod hm = (HandlerMethod) mapping.getHandler(request).getHandler();
assertEquals(fooParamMethod.getMethod(), hm.getMethod());
} }
@Test @Test
public void methodNotAllowed() throws Exception { public void methodNotAllowed() throws Exception {
try { try {
mapping.getHandlerInternal(new MockHttpServletRequest("POST", "/bar")); MockHttpServletRequest request = new MockHttpServletRequest("POST", "/bar");
mapping.getHandler(request);
fail("HttpRequestMethodNotSupportedException expected"); fail("HttpRequestMethodNotSupportedException expected");
} }
catch (HttpRequestMethodNotSupportedException ex) { catch (HttpRequestMethodNotSupportedException ex) {
@ -109,7 +132,6 @@ public class RequestMappingHandlerMethodMappingTests {
HandlerInterceptor interceptor = new HandlerInterceptorAdapter() {}; HandlerInterceptor interceptor = new HandlerInterceptorAdapter() {};
MappedInterceptor mappedInterceptor = new MappedInterceptor(new String[] {path}, interceptor); MappedInterceptor mappedInterceptor = new MappedInterceptor(new String[] {path}, interceptor);
MyRequestMappingHandlerMethodMapping mapping = new MyRequestMappingHandlerMethodMapping();
mapping.setMappedInterceptors(new MappedInterceptor[] { mappedInterceptor }); mapping.setMappedInterceptors(new MappedInterceptor[] { mappedInterceptor });
HandlerExecutionChain chain = mapping.getHandlerExecutionChain(handler, new MockHttpServletRequest("GET", path)); HandlerExecutionChain chain = mapping.getHandlerExecutionChain(handler, new MockHttpServletRequest("GET", path));
@ -120,27 +142,21 @@ public class RequestMappingHandlerMethodMappingTests {
assertNull(chain.getInterceptors()); 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") @SuppressWarnings("unused")
@Controller
private static class Handler {
@RequestMapping(value = "/foo", method = RequestMethod.GET) @RequestMapping(value = "/foo", method = RequestMethod.GET)
public void foo() { public void foo() {
} }
@SuppressWarnings("unused") @RequestMapping(value = "/foo", method = RequestMethod.GET, params="p")
public void fooParam() {
}
@RequestMapping(value = "/ba*", method = { RequestMethod.GET, RequestMethod.HEAD }) @RequestMapping(value = "/ba*", method = { RequestMethod.GET, RequestMethod.HEAD })
public void bar() { public void bar() {
} }
} }
} }

View File

@ -17,57 +17,124 @@
package org.springframework.web.servlet.mvc.method.annotation; package org.springframework.web.servlet.mvc.method.annotation;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import javax.servlet.http.HttpServletResponse;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolverComposite;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite; import org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite;
import org.springframework.web.method.support.ModelAndViewContainer; import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.method.annotation.support.DefaultMethodReturnValueHandler; import org.springframework.web.servlet.mvc.method.annotation.support.ServletResponseMethodArgumentResolver;
/** /**
* Test fixture for {@link ServletInvocableHandlerMethod} unit tests. * Test fixture with {@link ServletInvocableHandlerMethod}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
public class ServletInvocableHandlerMethodTests { public class ServletInvocableHandlerMethodTests {
private final Object handler = new Handler();
private HandlerMethodArgumentResolverComposite argumentResolvers;
private HandlerMethodReturnValueHandlerComposite returnValueHandlers;
private ModelAndViewContainer mavContainer;
private ServletWebRequest webRequest; private ServletWebRequest webRequest;
private MockHttpServletResponse response; private MockHttpServletResponse response;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
returnValueHandlers = new HandlerMethodReturnValueHandlerComposite();
argumentResolvers = new HandlerMethodArgumentResolverComposite();
mavContainer = new ModelAndViewContainer();
response = new MockHttpServletResponse(); response = new MockHttpServletResponse();
this.webRequest = new ServletWebRequest(new MockHttpServletRequest(), response); webRequest = new ServletWebRequest(new MockHttpServletRequest(), response);
} }
@Test @Test
public void setResponseStatus() throws Exception { public void setResponseStatus() throws Exception {
HandlerMethodReturnValueHandlerComposite handlers = new HandlerMethodReturnValueHandlerComposite(); returnValueHandlers.addHandler(new ExceptionThrowingReturnValueHandler());
handlers.registerReturnValueHandler(new DefaultMethodReturnValueHandler(null)); handlerMethod("responseStatus").invokeAndHandle(webRequest, mavContainer);
Method method = Handler.class.getDeclaredMethod("responseStatus"); assertFalse("Null return value with an @ResponseStatus should result in 'no view resolution'",
ServletInvocableHandlerMethod handlerMethod = new ServletInvocableHandlerMethod(new Handler(), method); mavContainer.isResolveView());
handlerMethod.setHandlerMethodReturnValueHandlers(handlers);
handlerMethod.invokeAndHandle(webRequest, new ModelAndViewContainer());
assertEquals(HttpStatus.BAD_REQUEST.value(), response.getStatus()); assertEquals(HttpStatus.BAD_REQUEST.value(), response.getStatus());
assertEquals("400 Bad Request", response.getErrorMessage()); assertEquals("400 Bad Request", response.getErrorMessage());
} }
private static class Handler { @Test
public void checkNoViewResolutionWithHttpServletResponse() throws Exception {
argumentResolvers.addResolver(new ServletResponseMethodArgumentResolver());
returnValueHandlers.addHandler(new ExceptionThrowingReturnValueHandler());
handlerMethod("httpServletResponse", HttpServletResponse.class).invokeAndHandle(webRequest, mavContainer);
assertFalse("Null return value with an HttpServletResponse argument should result in 'no view resolution'",
mavContainer.isResolveView());
}
@Test
public void checkNoViewResolutionWithRequestNotModified() throws Exception {
returnValueHandlers.addHandler(new ExceptionThrowingReturnValueHandler());
webRequest.getNativeRequest(MockHttpServletRequest.class).addHeader("If-Modified-Since", 10 * 1000 * 1000);
int lastModifiedTimestamp = 1000 * 1000;
webRequest.checkNotModified(lastModifiedTimestamp);
handlerMethod("notModified").invokeAndHandle(webRequest, mavContainer);
assertFalse("Null return value with a 'not modified' request should result in 'no view resolution'",
mavContainer.isResolveView());
}
private ServletInvocableHandlerMethod handlerMethod(String methodName, Class<?>...paramTypes)
throws NoSuchMethodException {
Method method = handler.getClass().getDeclaredMethod(methodName, paramTypes);
ServletInvocableHandlerMethod handlerMethod = new ServletInvocableHandlerMethod(handler, method);
handlerMethod.setHandlerMethodArgumentResolvers(argumentResolvers);
handlerMethod.setHandlerMethodReturnValueHandlers(returnValueHandlers);
return handlerMethod;
}
private static class ExceptionThrowingReturnValueHandler implements HandlerMethodReturnValueHandler {
public boolean supportsReturnType(MethodParameter returnType) {
return true;
}
public void handleReturnValue(Object returnValue, MethodParameter returnType,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
throw new IllegalStateException("Should never be invoked");
}
}
@SuppressWarnings("unused") @SuppressWarnings("unused")
private static class Handler {
@ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "400 Bad Request") @ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "400 Bad Request")
public void responseStatus() { public void responseStatus() {
} }
public void httpServletResponse(HttpServletResponse response) {
}
public void notModified() {
} }
} }
}

View File

@ -16,10 +16,14 @@
package org.springframework.web.servlet.mvc.method.annotation.support; package org.springframework.web.servlet.mvc.method.annotation.support;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@ -27,11 +31,14 @@ import org.springframework.beans.TestBean;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.ui.ExtendedModelMap; import org.springframework.ui.ExtendedModelMap;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.support.ModelAndViewContainer; import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.annotation.ModelAndViewResolver;
/** /**
* Test fixture for {@link DefaultMethodReturnValueHandler} unit tests. * Test fixture with {@link DefaultMethodReturnValueHandler}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
@ -39,53 +46,90 @@ public class DefaultMethodReturnValueHandlerTests {
private DefaultMethodReturnValueHandler handler; private DefaultMethodReturnValueHandler handler;
private ServletWebRequest webRequest; private List<ModelAndViewResolver> mavResolvers;
private ModelAndViewContainer mavContainer; private ModelAndViewContainer mavContainer;
private ServletWebRequest request;
@Before @Before
public void setUp() { public void setUp() {
this.handler = new DefaultMethodReturnValueHandler(null); mavResolvers = new ArrayList<ModelAndViewResolver>();
this.mavContainer = new ModelAndViewContainer(new ExtendedModelMap()); handler = new DefaultMethodReturnValueHandler(mavResolvers);
this.webRequest = new ServletWebRequest(new MockHttpServletRequest()); mavContainer = new ModelAndViewContainer(new ExtendedModelMap());
} request = new ServletWebRequest(new MockHttpServletRequest());
@Test(expected=UnsupportedOperationException.class)
public void returnSimpleType() throws Exception {
handler.handleReturnValue(55, createMethodParam("simpleType"), mavContainer, webRequest);
} }
@Test @Test
public void returnVoid() throws Exception { public void modelAndViewResolver() throws Exception {
handler.handleReturnValue(null, null, mavContainer, webRequest); MethodParameter testBeanType = new MethodParameter(getClass().getDeclaredMethod("testBeanReturnValue"), -1);
mavResolvers.add(new TestModelAndViewResolver(TestBean.class));
TestBean testBean = new TestBean("name");
handler.handleReturnValue(testBean, testBeanType, mavContainer, request);
assertEquals("viewName", mavContainer.getViewName());
assertSame(testBean, mavContainer.getAttribute("modelAttrName"));
assertTrue(mavContainer.isResolveView());
}
@Test(expected=UnsupportedOperationException.class)
public void modelAndViewResolverUnresolved() throws Exception {
MethodParameter testBeanType = new MethodParameter(getClass().getDeclaredMethod("testBeanReturnValue"), -1);
mavResolvers.add(new TestModelAndViewResolver(TestBean.class));
handler.handleReturnValue(99, testBeanType, mavContainer, request);
}
@Test
public void handleNull() throws Exception {
handler.handleReturnValue(null, null, mavContainer, request);
assertNull(mavContainer.getView()); assertNull(mavContainer.getView());
assertNull(mavContainer.getViewName()); assertNull(mavContainer.getViewName());
assertTrue(mavContainer.getModel().isEmpty()); assertTrue(mavContainer.getModel().isEmpty());
} }
@Test(expected=UnsupportedOperationException.class)
public void handleSimpleType() throws Exception {
MethodParameter intType = new MethodParameter(getClass().getDeclaredMethod("intReturnValue"), -1);
handler.handleReturnValue(55, intType, mavContainer, request);
}
@Test @Test
public void returnSingleModelAttribute() throws Exception{ public void handleNonSimpleType() throws Exception{
handler.handleReturnValue(new TestBean(), createMethodParam("singleModelAttribute"), mavContainer, webRequest); MethodParameter testBeanType = new MethodParameter(getClass().getDeclaredMethod("testBeanReturnValue"), -1);
handler.handleReturnValue(new TestBean(), testBeanType, mavContainer, request);
assertTrue(mavContainer.containsAttribute("testBean")); assertTrue(mavContainer.containsAttribute("testBean"));
} }
private MethodParameter createMethodParam(String methodName) throws Exception {
Method method = getClass().getDeclaredMethod(methodName);
return new MethodParameter(method, -1);
}
@SuppressWarnings("unused") @SuppressWarnings("unused")
private int simpleType() { private int intReturnValue() {
return 0; return 0;
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
private void voidReturnValue() { private TestBean testBeanReturnValue() {
}
@SuppressWarnings("unused")
private TestBean singleModelAttribute() {
return null; return null;
} }
private static class TestModelAndViewResolver implements ModelAndViewResolver {
private Class<?> returnValueType;
public TestModelAndViewResolver(Class<?> returnValueType) {
this.returnValueType = returnValueType;
}
@SuppressWarnings("rawtypes")
public ModelAndView resolveModelAndView(Method method, Class handlerType, Object returnValue,
ExtendedModelMap model, NativeWebRequest request) {
if (returnValue != null && returnValue.getClass().equals(returnValueType)) {
return new ModelAndView("viewName", "modelAttrName", returnValue);
}
else {
return ModelAndViewResolver.UNRESOLVED;
}
}
}
} }

View File

@ -16,6 +16,7 @@
package org.springframework.web.servlet.mvc.method.annotation.support; package org.springframework.web.servlet.mvc.method.annotation.support;
import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.createMock; import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.eq; import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect; import static org.easymock.EasyMock.expect;
@ -25,12 +26,14 @@ import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import org.easymock.Capture;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
@ -42,17 +45,18 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.HttpMediaTypeNotAcceptableException; import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpMediaTypeNotSupportedException; import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.support.ModelAndViewContainer; import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.method.annotation.support.HttpEntityMethodProcessor;
/** /**
* Test fixture with {@link HttpEntityMethodProcessor} and mock {@link HttpMessageConverter}.
*
* @author Arjen Poutsma * @author Arjen Poutsma
* @author Rossen Stoyanchev
*/ */
public class HttpEntityMethodProcessorTests { public class HttpEntityMethodProcessorTests {
@ -60,26 +64,21 @@ public class HttpEntityMethodProcessorTests {
private HttpMessageConverter<String> messageConverter; private HttpMessageConverter<String> messageConverter;
private MethodParameter httpEntityParam; private MethodParameter paramHttpEntity;
private MethodParameter paramResponseEntity;
private MethodParameter responseEntityReturnValue; private MethodParameter paramInt;
private MethodParameter returnTypeResponseEntity;
private MethodParameter responseEntityParameter; private MethodParameter returnTypeHttpEntity;
private MethodParameter returnTypeInt;
private MethodParameter intReturnValue;
private MethodParameter httpEntityReturnValue;
private MethodParameter intParameter;
private ModelAndViewContainer mavContainer; private ModelAndViewContainer mavContainer;
private ServletWebRequest request; private ServletWebRequest webRequest;
private MockHttpServletRequest servletRequest;
private MockHttpServletResponse servletResponse; private MockHttpServletResponse servletResponse;
private MockHttpServletRequest servletRequest;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
@ -90,95 +89,87 @@ public class HttpEntityMethodProcessorTests {
processor = new HttpEntityMethodProcessor(messageConverters); processor = new HttpEntityMethodProcessor(messageConverters);
Method handle1 = getClass().getMethod("handle1", HttpEntity.class, ResponseEntity.class, Integer.TYPE); Method handle1 = getClass().getMethod("handle1", HttpEntity.class, ResponseEntity.class, Integer.TYPE);
httpEntityParam = new MethodParameter(handle1, 0); paramHttpEntity = new MethodParameter(handle1, 0);
responseEntityParameter = new MethodParameter(handle1, 1); paramResponseEntity = new MethodParameter(handle1, 1);
intParameter = new MethodParameter(handle1, 2); paramInt = new MethodParameter(handle1, 2);
responseEntityReturnValue = new MethodParameter(handle1, -1); returnTypeResponseEntity = new MethodParameter(handle1, -1);
Method handle2 = getClass().getMethod("handle2", HttpEntity.class); returnTypeHttpEntity = new MethodParameter(getClass().getMethod("handle2", HttpEntity.class), -1);
httpEntityReturnValue = new MethodParameter(handle2, -1); returnTypeInt = new MethodParameter(getClass().getMethod("handle3"), -1);
Method other = getClass().getMethod("otherMethod");
intReturnValue = new MethodParameter(other, -1);
mavContainer = new ModelAndViewContainer(); mavContainer = new ModelAndViewContainer();
servletRequest = new MockHttpServletRequest(); servletRequest = new MockHttpServletRequest();
servletResponse = new MockHttpServletResponse(); servletResponse = new MockHttpServletResponse();
request = new ServletWebRequest(servletRequest, servletResponse); webRequest = new ServletWebRequest(servletRequest, servletResponse);
} }
@Test @Test
public void supportsParameter() { public void supportsParameter() {
assertTrue("HttpEntity parameter not supported", processor.supportsParameter(httpEntityParam)); assertTrue("HttpEntity parameter not supported", processor.supportsParameter(paramHttpEntity));
assertFalse("ResponseEntity parameter supported", processor.supportsParameter(responseEntityParameter)); assertFalse("ResponseEntity parameter supported", processor.supportsParameter(paramResponseEntity));
assertFalse("non-entity parameter supported", processor.supportsParameter(intParameter)); assertFalse("non-entity parameter supported", processor.supportsParameter(paramInt));
} }
@Test @Test
public void supportsReturnType() { public void supportsReturnType() {
assertTrue("ResponseEntity return type not supported", processor.supportsReturnType(responseEntityReturnValue)); assertTrue("ResponseEntity return type not supported", processor.supportsReturnType(returnTypeResponseEntity));
assertTrue("HttpEntity return type not supported", processor.supportsReturnType(httpEntityReturnValue)); assertTrue("HttpEntity return type not supported", processor.supportsReturnType(returnTypeHttpEntity));
assertFalse("non-ResponseBody return type supported", processor.supportsReturnType(intReturnValue)); assertFalse("non-ResponseBody return type supported", processor.supportsReturnType(returnTypeInt));
} }
@Test @Test
@SuppressWarnings("unchecked")
public void resolveArgument() throws Exception { public void resolveArgument() throws Exception {
MediaType contentType = MediaType.TEXT_PLAIN; MediaType contentType = MediaType.TEXT_PLAIN;
String expected = "Foo";
servletRequest.addHeader("Content-Type", contentType.toString()); servletRequest.addHeader("Content-Type", contentType.toString());
String body = "Foo";
expect(messageConverter.getSupportedMediaTypes()).andReturn(Arrays.asList(contentType)); expect(messageConverter.getSupportedMediaTypes()).andReturn(Arrays.asList(contentType));
expect(messageConverter.canRead(String.class, contentType)).andReturn(true); expect(messageConverter.canRead(String.class, contentType)).andReturn(true);
expect(messageConverter.read(eq(String.class), isA(HttpInputMessage.class))).andReturn(expected); expect(messageConverter.read(eq(String.class), isA(HttpInputMessage.class))).andReturn(body);
replay(messageConverter); replay(messageConverter);
HttpEntity<?> result = (HttpEntity<String>) processor.resolveArgument(httpEntityParam, mavContainer, request, null); Object result = processor.resolveArgument(paramHttpEntity, mavContainer, webRequest, null);
assertTrue(result instanceof HttpEntity);
assertTrue("The ResolveView flag shouldn't change", mavContainer.isResolveView()); assertTrue("The ResolveView flag shouldn't change", mavContainer.isResolveView());
assertEquals("Invalid argument", expected, result.getBody()); assertEquals("Invalid argument", body, ((HttpEntity<?>) result).getBody());
verify(messageConverter); verify(messageConverter);
} }
@Test(expected = HttpMediaTypeNotSupportedException.class) @Test(expected = HttpMediaTypeNotSupportedException.class)
public void resolveArgumentNotReadable() throws Exception { public void resolveArgumentNotReadable() throws Exception {
MediaType contentType = MediaType.TEXT_PLAIN; MediaType contentType = MediaType.TEXT_PLAIN;
servletRequest.addHeader("Content-Type", contentType.toString()); servletRequest.addHeader("Content-Type", contentType.toString());
expect(messageConverter.getSupportedMediaTypes()).andReturn(Arrays.asList(contentType)); expect(messageConverter.getSupportedMediaTypes()).andReturn(Arrays.asList(contentType));
expect(messageConverter.canRead(String.class, contentType)).andReturn(false); expect(messageConverter.canRead(String.class, contentType)).andReturn(false);
replay(messageConverter); replay(messageConverter);
processor.resolveArgument(httpEntityParam, mavContainer, request, null); processor.resolveArgument(paramHttpEntity, mavContainer, webRequest, null);
assertTrue("The ResolveView flag shouldn't change", mavContainer.isResolveView()); fail("Expected exception");
verify(messageConverter);
} }
@Test(expected = HttpMediaTypeNotSupportedException.class) @Test(expected = HttpMediaTypeNotSupportedException.class)
public void resolveArgumentNoContentType() throws Exception { public void resolveArgumentNoContentType() throws Exception {
processor.resolveArgument(httpEntityParam, mavContainer, request, null); processor.resolveArgument(paramHttpEntity, mavContainer, webRequest, null);
fail("Expected exception");
} }
@Test @Test
public void handleReturnValue() throws Exception { public void handleReturnValue() throws Exception {
MediaType accepted = MediaType.TEXT_PLAIN; String body = "Foo";
String s = "Foo"; ResponseEntity<String> returnValue = new ResponseEntity<String>(body, HttpStatus.OK);
ResponseEntity<String> returnValue = new ResponseEntity<String>(s, HttpStatus.OK);
MediaType accepted = MediaType.TEXT_PLAIN;
servletRequest.addHeader("Accept", accepted.toString()); servletRequest.addHeader("Accept", accepted.toString());
expect(messageConverter.canWrite(String.class, accepted)).andReturn(true); expect(messageConverter.canWrite(String.class, accepted)).andReturn(true);
messageConverter.write(eq(s), eq(accepted), isA(HttpOutputMessage.class)); messageConverter.write(eq(body), eq(accepted), isA(HttpOutputMessage.class));
replay(messageConverter); replay(messageConverter);
processor.handleReturnValue(returnValue, responseEntityReturnValue, mavContainer, request); processor.handleReturnValue(returnValue, returnTypeResponseEntity, mavContainer, webRequest);
assertFalse(mavContainer.isResolveView()); assertFalse(mavContainer.isResolveView());
verify(messageConverter); verify(messageConverter);
@ -186,36 +177,31 @@ public class HttpEntityMethodProcessorTests {
@Test(expected = HttpMediaTypeNotAcceptableException.class) @Test(expected = HttpMediaTypeNotAcceptableException.class)
public void handleReturnValueNotAcceptable() throws Exception { public void handleReturnValueNotAcceptable() throws Exception {
MediaType accepted = MediaType.TEXT_PLAIN; String body = "Foo";
String s = "Foo"; ResponseEntity<String> returnValue = new ResponseEntity<String>(body, HttpStatus.OK);
ResponseEntity<String> returnValue = new ResponseEntity<String>(s, HttpStatus.OK);
MediaType accepted = MediaType.TEXT_PLAIN;
servletRequest.addHeader("Accept", accepted.toString()); servletRequest.addHeader("Accept", accepted.toString());
expect(messageConverter.canWrite(String.class, accepted)).andReturn(false); expect(messageConverter.canWrite(String.class, accepted)).andReturn(false);
expect(messageConverter.getSupportedMediaTypes()).andReturn(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM)); expect(messageConverter.getSupportedMediaTypes()).andReturn(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM));
replay(messageConverter); replay(messageConverter);
processor.handleReturnValue(returnValue, responseEntityReturnValue, mavContainer, request); processor.handleReturnValue(returnValue, returnTypeResponseEntity, mavContainer, webRequest);
assertFalse(mavContainer.isResolveView()); fail("Expected exception");
verify(messageConverter);
} }
@Test @Test
public void responseHeaderNoBody() throws Exception { public void responseHeaderNoBody() throws Exception {
HttpHeaders responseHeaders = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
responseHeaders.set("header", "headerValue"); headers.set("headerName", "headerValue");
ResponseEntity<String> returnValue = new ResponseEntity<String>(responseHeaders, HttpStatus.ACCEPTED); ResponseEntity<String> returnValue = new ResponseEntity<String>(headers, HttpStatus.ACCEPTED);
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>(); processor.handleReturnValue(returnValue, returnTypeResponseEntity, mavContainer, webRequest);
messageConverters.add(new StringHttpMessageConverter());
HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(messageConverters);
processor.handleReturnValue(returnValue, responseEntityReturnValue, mavContainer, request);
assertFalse(mavContainer.isResolveView()); assertFalse(mavContainer.isResolveView());
assertEquals("headerValue", servletResponse.getHeader("header")); assertEquals("headerValue", servletResponse.getHeader("headerName"));
} }
@Test @Test
@ -224,13 +210,16 @@ public class HttpEntityMethodProcessorTests {
responseHeaders.set("header", "headerValue"); responseHeaders.set("header", "headerValue");
ResponseEntity<String> returnValue = new ResponseEntity<String>("body", responseHeaders, HttpStatus.ACCEPTED); ResponseEntity<String> returnValue = new ResponseEntity<String>("body", responseHeaders, HttpStatus.ACCEPTED);
List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>(); Capture<HttpOutputMessage> outputMessage = new Capture<HttpOutputMessage>();
messageConverters.add(new StringHttpMessageConverter()); expect(messageConverter.canWrite(String.class, MediaType.ALL)).andReturn(true);
HttpEntityMethodProcessor processor = new HttpEntityMethodProcessor(messageConverters); messageConverter.write(eq("body"), eq(MediaType.ALL), capture(outputMessage));
processor.handleReturnValue(returnValue, responseEntityReturnValue, mavContainer, request); replay(messageConverter);
processor.handleReturnValue(returnValue, returnTypeResponseEntity, mavContainer, webRequest);
assertFalse(mavContainer.isResolveView()); assertFalse(mavContainer.isResolveView());
assertEquals("headerValue", servletResponse.getHeader("header")); assertEquals("headerValue", outputMessage.getValue().getHeaders().get("header").get(0));
verify(messageConverter);
} }
public ResponseEntity<String> handle1(HttpEntity<String> httpEntity, ResponseEntity<String> responseEntity, int i) { public ResponseEntity<String> handle1(HttpEntity<String> httpEntity, ResponseEntity<String> responseEntity, int i) {
@ -241,13 +230,7 @@ public class HttpEntityMethodProcessorTests {
return entity; return entity;
} }
public HttpEntity<?> handle3() { public int handle3() {
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.set("header", "headerValue");
return new ResponseEntity<String>(responseHeaders, HttpStatus.OK);
}
public int otherMethod() {
return 42; return 42;
} }

View File

@ -36,53 +36,53 @@ import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.mvc.method.annotation.support.PathVariableMethodArgumentResolver; import org.springframework.web.servlet.mvc.method.annotation.support.PathVariableMethodArgumentResolver;
/** /**
* Test fixture with {@link PathVariableMethodArgumentResolver}.
*
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
public class PathVariableMethodArgumentResolverTests { public class PathVariableMethodArgumentResolverTests {
private PathVariableMethodArgumentResolver resolver; private PathVariableMethodArgumentResolver resolver;
private MethodParameter pathVarParam; private MethodParameter paramNamedString;
private MethodParameter stringParam; private MethodParameter paramString;
private MockHttpServletRequest servletRequest;
private ServletWebRequest webRequest; private ServletWebRequest webRequest;
private MockHttpServletRequest request;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
resolver = new PathVariableMethodArgumentResolver(); resolver = new PathVariableMethodArgumentResolver();
Method method = getClass().getMethod("handle", String.class, String.class);
pathVarParam = new MethodParameter(method, 0);
stringParam = new MethodParameter(method, 1);
servletRequest = new MockHttpServletRequest(); Method method = getClass().getMethod("handle", String.class, String.class);
MockHttpServletResponse servletResponse = new MockHttpServletResponse(); paramNamedString = new MethodParameter(method, 0);
webRequest = new ServletWebRequest(servletRequest, servletResponse); paramString = new MethodParameter(method, 1);
request = new MockHttpServletRequest();
webRequest = new ServletWebRequest(request, new MockHttpServletResponse());
} }
@Test @Test
public void supportsParameter() { public void supportsParameter() {
assertTrue("Parameter with @PathVariable annotation", resolver.supportsParameter(pathVarParam)); assertTrue("Parameter with @PathVariable annotation", resolver.supportsParameter(paramNamedString));
assertFalse("Parameter without @PathVariable annotation", resolver.supportsParameter(stringParam)); assertFalse("Parameter without @PathVariable annotation", resolver.supportsParameter(paramString));
} }
@Test @Test
public void resolveStringArgument() throws Exception { public void resolveStringArgument() throws Exception {
String expected = "foo";
Map<String, String> uriTemplateVars = new HashMap<String, String>(); Map<String, String> uriTemplateVars = new HashMap<String, String>();
uriTemplateVars.put("name", expected); uriTemplateVars.put("name", "value");
servletRequest.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars); request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVars);
String result = (String) resolver.resolveArgument(pathVarParam, null, webRequest, null); String result = (String) resolver.resolveArgument(paramNamedString, null, webRequest, null);
assertEquals(expected, result); assertEquals("value", result);
} }
@Test(expected = IllegalStateException.class) @Test(expected = IllegalStateException.class)
public void handleMissingValue() throws Exception { public void handleMissingValue() throws Exception {
resolver.resolveArgument(pathVarParam, null, webRequest, null); resolver.resolveArgument(paramNamedString, null, webRequest, null);
fail("Unresolved path variable should lead to exception."); fail("Unresolved path variable should lead to exception.");
} }

View File

@ -25,6 +25,7 @@ import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
@ -49,7 +50,10 @@ import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.support.ModelAndViewContainer; import org.springframework.web.method.support.ModelAndViewContainer;
/** /**
* Test fixture with {@link RequestResponseBodyMethodProcessor} and mock {@link HttpMessageConverter}.
*
* @author Arjen Poutsma * @author Arjen Poutsma
* @author Rossen Stoyanchev
*/ */
public class RequestResponseBodyMethodProcessorTests { public class RequestResponseBodyMethodProcessorTests {
@ -57,13 +61,10 @@ public class RequestResponseBodyMethodProcessorTests {
private HttpMessageConverter<String> messageConverter; private HttpMessageConverter<String> messageConverter;
private MethodParameter stringParameter; private MethodParameter paramRequestBodyString;
private MethodParameter paramInt;
private MethodParameter stringReturnValue; private MethodParameter returnTypeString;
private MethodParameter returnTypeInt;
private MethodParameter intParameter;
private MethodParameter intReturnValue;
private ModelAndViewContainer mavContainer; private ModelAndViewContainer mavContainer;
@ -80,88 +81,80 @@ public class RequestResponseBodyMethodProcessorTests {
messageConverters.add(messageConverter); messageConverters.add(messageConverter);
processor = new RequestResponseBodyMethodProcessor(messageConverters); processor = new RequestResponseBodyMethodProcessor(messageConverters);
Method handle = getClass().getMethod("handle", String.class, Integer.TYPE); Method handle = getClass().getMethod("handle1", String.class, Integer.TYPE);
stringParameter = new MethodParameter(handle, 0); paramRequestBodyString = new MethodParameter(handle, 0);
intParameter = new MethodParameter(handle, 1); paramInt = new MethodParameter(handle, 1);
stringReturnValue = new MethodParameter(handle, -1); returnTypeString = new MethodParameter(handle, -1);
Method other = getClass().getMethod("otherMethod"); returnTypeInt = new MethodParameter(getClass().getMethod("handle2"), -1);
intReturnValue = new MethodParameter(other, -1);
mavContainer = new ModelAndViewContainer(); mavContainer = new ModelAndViewContainer();
servletRequest = new MockHttpServletRequest(); servletRequest = new MockHttpServletRequest();
MockHttpServletResponse servletResponse = new MockHttpServletResponse(); webRequest = new ServletWebRequest(servletRequest, new MockHttpServletResponse());
webRequest = new ServletWebRequest(servletRequest, servletResponse);
} }
@Test @Test
public void supportsParameter() { public void supportsParameter() {
assertTrue("RequestBody parameter not supported", processor.supportsParameter(stringParameter)); assertTrue("RequestBody parameter not supported", processor.supportsParameter(paramRequestBodyString));
assertFalse("non-RequestBody parameter supported", processor.supportsParameter(intParameter)); assertFalse("non-RequestBody parameter supported", processor.supportsParameter(paramInt));
} }
@Test @Test
public void supportsReturnType() { public void supportsReturnType() {
assertTrue("ResponseBody return type not supported", processor.supportsReturnType(stringReturnValue)); assertTrue("ResponseBody return type not supported", processor.supportsReturnType(returnTypeString));
assertFalse("non-ResponseBody return type supported", processor.supportsReturnType(intReturnValue)); assertFalse("non-ResponseBody return type supported", processor.supportsReturnType(returnTypeInt));
} }
@Test @Test
public void resolveArgument() throws Exception { public void resolveArgument() throws Exception {
MediaType contentType = MediaType.TEXT_PLAIN; MediaType contentType = MediaType.TEXT_PLAIN;
String expected = "Foo";
servletRequest.addHeader("Content-Type", contentType.toString()); servletRequest.addHeader("Content-Type", contentType.toString());
String body = "Foo";
expect(messageConverter.getSupportedMediaTypes()).andReturn(Arrays.asList(contentType)); expect(messageConverter.getSupportedMediaTypes()).andReturn(Arrays.asList(contentType));
expect(messageConverter.canRead(String.class, contentType)).andReturn(true); expect(messageConverter.canRead(String.class, contentType)).andReturn(true);
expect(messageConverter.read(eq(String.class), isA(HttpInputMessage.class))).andReturn(expected); expect(messageConverter.read(eq(String.class), isA(HttpInputMessage.class))).andReturn(body);
replay(messageConverter); replay(messageConverter);
Object result = processor.resolveArgument(stringParameter, mavContainer, webRequest, null); Object result = processor.resolveArgument(paramRequestBodyString, mavContainer, webRequest, null);
assertEquals("Invalid argument", expected, result); assertEquals("Invalid argument", body, result);
assertTrue("The ResolveView flag shouldn't change", mavContainer.isResolveView()); assertTrue("The ResolveView flag shouldn't change", mavContainer.isResolveView());
verify(messageConverter); verify(messageConverter);
} }
@Test(expected = HttpMediaTypeNotSupportedException.class) @Test(expected = HttpMediaTypeNotSupportedException.class)
public void resolveArgumentNotReadable() throws Exception { public void resolveArgumentNotReadable() throws Exception {
MediaType contentType = MediaType.TEXT_PLAIN; MediaType contentType = MediaType.TEXT_PLAIN;
servletRequest.addHeader("Content-Type", contentType.toString()); servletRequest.addHeader("Content-Type", contentType.toString());
expect(messageConverter.getSupportedMediaTypes()).andReturn(Arrays.asList(contentType)); expect(messageConverter.getSupportedMediaTypes()).andReturn(Arrays.asList(contentType));
expect(messageConverter.canRead(String.class, contentType)).andReturn(false); expect(messageConverter.canRead(String.class, contentType)).andReturn(false);
replay(messageConverter); replay(messageConverter);
processor.resolveArgument(stringParameter, mavContainer, webRequest, null); processor.resolveArgument(paramRequestBodyString, mavContainer, webRequest, null);
assertTrue("The ResolveView flag shouldn't change", mavContainer.isResolveView()); fail("Expected exception");
verify(messageConverter);
} }
@Test(expected = HttpMediaTypeNotSupportedException.class) @Test(expected = HttpMediaTypeNotSupportedException.class)
public void resolveArgumentNoContentType() throws Exception { public void resolveArgumentNoContentType() throws Exception {
processor.resolveArgument(stringParameter, mavContainer, webRequest, null); processor.resolveArgument(paramRequestBodyString, mavContainer, webRequest, null);
fail("Expected exception");
} }
@Test @Test
public void handleReturnValue() throws Exception { public void handleReturnValue() throws Exception {
MediaType accepted = MediaType.TEXT_PLAIN; MediaType accepted = MediaType.TEXT_PLAIN;
String returnValue = "Foo";
servletRequest.addHeader("Accept", accepted.toString()); servletRequest.addHeader("Accept", accepted.toString());
String body = "Foo";
expect(messageConverter.canWrite(String.class, accepted)).andReturn(true); expect(messageConverter.canWrite(String.class, accepted)).andReturn(true);
messageConverter.write(eq(returnValue), eq(accepted), isA(HttpOutputMessage.class)); messageConverter.write(eq(body), eq(accepted), isA(HttpOutputMessage.class));
replay(messageConverter); replay(messageConverter);
processor.handleReturnValue(returnValue, stringReturnValue, mavContainer, webRequest); processor.handleReturnValue(body, returnTypeString, mavContainer, webRequest);
assertFalse("The ResolveView flag wasn't turned off", mavContainer.isResolveView()); assertFalse("The ResolveView flag wasn't turned off", mavContainer.isResolveView());
verify(messageConverter); verify(messageConverter);
@ -170,27 +163,23 @@ public class RequestResponseBodyMethodProcessorTests {
@Test(expected = HttpMediaTypeNotAcceptableException.class) @Test(expected = HttpMediaTypeNotAcceptableException.class)
public void handleReturnValueNotAcceptable() throws Exception { public void handleReturnValueNotAcceptable() throws Exception {
MediaType accepted = MediaType.TEXT_PLAIN; MediaType accepted = MediaType.TEXT_PLAIN;
String returnValue = "Foo";
servletRequest.addHeader("Accept", accepted.toString()); servletRequest.addHeader("Accept", accepted.toString());
expect(messageConverter.canWrite(String.class, accepted)).andReturn(false); expect(messageConverter.canWrite(String.class, accepted)).andReturn(false);
expect(messageConverter.getSupportedMediaTypes()).andReturn(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM)); expect(messageConverter.getSupportedMediaTypes()).andReturn(Arrays.asList(MediaType.APPLICATION_OCTET_STREAM));
replay(messageConverter); replay(messageConverter);
processor.handleReturnValue(returnValue, stringReturnValue, mavContainer, webRequest); processor.handleReturnValue("Foo", returnTypeString, mavContainer, webRequest);
assertFalse("The ResolveView flag wasn't turned off", mavContainer.isResolveView()); fail("Expected exception");
verify(messageConverter);
} }
@ResponseBody @ResponseBody
public String handle(@RequestBody String s, int i) { public String handle1(@RequestBody String s, int i) {
return s; return s;
} }
public int otherMethod() { public int handle2() {
return 42; return 42;
} }

View File

@ -17,8 +17,6 @@
package org.springframework.web.servlet.mvc.method.annotation.support; package org.springframework.web.servlet.mvc.method.annotation.support;
import static org.junit.Assert.assertEquals; 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.lang.reflect.Method;
@ -31,11 +29,12 @@ import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.bind.annotation.CookieValue; import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.annotation.support.AbstractCookieValueMethodArgumentResolver;
import org.springframework.web.servlet.mvc.method.annotation.support.ServletCookieValueMethodArgumentResolver;
/** /**
* Test fixture with {@link ServletCookieValueMethodArgumentResolver}.
*
* @author Arjen Poutsma * @author Arjen Poutsma
* @author Rossen Stoyanchev
*/ */
public class ServletCookieValueMethodArgumentResolverTests { public class ServletCookieValueMethodArgumentResolverTests {
@ -45,37 +44,26 @@ public class ServletCookieValueMethodArgumentResolverTests {
private MethodParameter cookieStringParameter; private MethodParameter cookieStringParameter;
private MethodParameter otherParameter;
private MockHttpServletRequest servletRequest;
private ServletWebRequest webRequest; private ServletWebRequest webRequest;
private MockHttpServletRequest request;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
resolver = new ServletCookieValueMethodArgumentResolver(null); resolver = new ServletCookieValueMethodArgumentResolver(null);
Method method = getClass().getMethod("params", Cookie.class, String.class, String.class);
Method method = getClass().getMethod("params", Cookie.class, String.class);
cookieParameter = new MethodParameter(method, 0); cookieParameter = new MethodParameter(method, 0);
cookieStringParameter = new MethodParameter(method, 1); cookieStringParameter = new MethodParameter(method, 1);
otherParameter = new MethodParameter(method, 2);
servletRequest = new MockHttpServletRequest(); request = new MockHttpServletRequest();
MockHttpServletResponse servletResponse = new MockHttpServletResponse(); webRequest = new ServletWebRequest(request, new MockHttpServletResponse());
webRequest = new ServletWebRequest(servletRequest, servletResponse);
}
@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 @Test
public void resolveCookieArgument() throws Exception { public void resolveCookieArgument() throws Exception {
Cookie expected = new Cookie("name", "foo"); Cookie expected = new Cookie("name", "foo");
servletRequest.setCookies(expected); request.setCookies(expected);
Cookie result = (Cookie) resolver.resolveArgument(cookieParameter, null, webRequest, null); Cookie result = (Cookie) resolver.resolveArgument(cookieParameter, null, webRequest, null);
assertEquals("Invalid result", expected, result); assertEquals("Invalid result", expected, result);
@ -84,29 +72,14 @@ public class ServletCookieValueMethodArgumentResolverTests {
@Test @Test
public void resolveCookieStringArgument() throws Exception { public void resolveCookieStringArgument() throws Exception {
Cookie cookie = new Cookie("name", "foo"); Cookie cookie = new Cookie("name", "foo");
servletRequest.setCookies(cookie); request.setCookies(cookie);
String result = (String) resolver.resolveArgument(cookieStringParameter, null, webRequest, null); String result = (String) resolver.resolveArgument(cookieStringParameter, null, webRequest, null);
assertEquals("Invalid result", cookie.getValue(), result); 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, public void params(@CookieValue("name") Cookie cookie,
@CookieValue(value = "name", defaultValue = "bar") String cookieString, @CookieValue(value = "name", defaultValue = "bar") String cookieString) {
String unsupported) {
} }
} }

View File

@ -40,13 +40,16 @@ import org.springframework.web.servlet.mvc.method.annotation.support.ServletRequ
import static org.junit.Assert.*; import static org.junit.Assert.*;
/** /**
* Test fixture with {@link ServletRequestMethodArgumentResolver}.
*
* @author Arjen Poutsma * @author Arjen Poutsma
* @author Rossen Stoyanchev
*/ */
public class ServletRequestMethodArgumentResolverTests { public class ServletRequestMethodArgumentResolverTests {
private ServletRequestMethodArgumentResolver resolver; private final ServletRequestMethodArgumentResolver resolver = new ServletRequestMethodArgumentResolver();
private Method supportedParams; private Method method;
private ModelAndViewContainer mavContainer; private ModelAndViewContainer mavContainer;
@ -56,10 +59,8 @@ public class ServletRequestMethodArgumentResolverTests {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
resolver = new ServletRequestMethodArgumentResolver(); method = getClass().getMethod("supportedParams", ServletRequest.class, MultipartRequest.class,
supportedParams = getClass() HttpSession.class, Principal.class, Locale.class, InputStream.class, Reader.class, WebRequest.class);
.getMethod("supportedParams", ServletRequest.class, MultipartRequest.class, HttpSession.class,
Principal.class, Locale.class, InputStream.class, Reader.class, WebRequest.class);
mavContainer = new ModelAndViewContainer(); mavContainer = new ModelAndViewContainer();
servletRequest = new MockHttpServletRequest(); servletRequest = new MockHttpServletRequest();
webRequest = new ServletWebRequest(servletRequest, new MockHttpServletResponse()); webRequest = new ServletWebRequest(servletRequest, new MockHttpServletResponse());
@ -67,7 +68,7 @@ public class ServletRequestMethodArgumentResolverTests {
@Test @Test
public void servletRequest() throws Exception { public void servletRequest() throws Exception {
MethodParameter servletRequestParameter = new MethodParameter(supportedParams, 0); MethodParameter servletRequestParameter = new MethodParameter(method, 0);
boolean isSupported = resolver.supportsParameter(servletRequestParameter); boolean isSupported = resolver.supportsParameter(servletRequestParameter);
Object result = resolver.resolveArgument(servletRequestParameter, mavContainer, webRequest, null); Object result = resolver.resolveArgument(servletRequestParameter, mavContainer, webRequest, null);
@ -81,7 +82,7 @@ public class ServletRequestMethodArgumentResolverTests {
public void session() throws Exception { public void session() throws Exception {
MockHttpSession session = new MockHttpSession(); MockHttpSession session = new MockHttpSession();
servletRequest.setSession(session); servletRequest.setSession(session);
MethodParameter sessionParameter = new MethodParameter(supportedParams, 2); MethodParameter sessionParameter = new MethodParameter(method, 2);
boolean isSupported = resolver.supportsParameter(sessionParameter); boolean isSupported = resolver.supportsParameter(sessionParameter);
Object result = resolver.resolveArgument(sessionParameter, mavContainer, webRequest, null); Object result = resolver.resolveArgument(sessionParameter, mavContainer, webRequest, null);
@ -99,7 +100,7 @@ public class ServletRequestMethodArgumentResolverTests {
} }
}; };
servletRequest.setUserPrincipal(principal); servletRequest.setUserPrincipal(principal);
MethodParameter principalParameter = new MethodParameter(supportedParams, 3); MethodParameter principalParameter = new MethodParameter(method, 3);
assertTrue("Principal not supported", resolver.supportsParameter(principalParameter)); assertTrue("Principal not supported", resolver.supportsParameter(principalParameter));
@ -111,7 +112,7 @@ public class ServletRequestMethodArgumentResolverTests {
public void locale() throws Exception { public void locale() throws Exception {
Locale locale = Locale.ENGLISH; Locale locale = Locale.ENGLISH;
servletRequest.addPreferredLocale(locale); servletRequest.addPreferredLocale(locale);
MethodParameter localeParameter = new MethodParameter(supportedParams, 4); MethodParameter localeParameter = new MethodParameter(method, 4);
assertTrue("Locale not supported", resolver.supportsParameter(localeParameter)); assertTrue("Locale not supported", resolver.supportsParameter(localeParameter));
@ -121,7 +122,7 @@ public class ServletRequestMethodArgumentResolverTests {
@Test @Test
public void inputStream() throws Exception { public void inputStream() throws Exception {
MethodParameter inputStreamParameter = new MethodParameter(supportedParams, 5); MethodParameter inputStreamParameter = new MethodParameter(method, 5);
assertTrue("InputStream not supported", resolver.supportsParameter(inputStreamParameter)); assertTrue("InputStream not supported", resolver.supportsParameter(inputStreamParameter));
@ -131,7 +132,7 @@ public class ServletRequestMethodArgumentResolverTests {
@Test @Test
public void reader() throws Exception { public void reader() throws Exception {
MethodParameter readerParameter = new MethodParameter(supportedParams, 6); MethodParameter readerParameter = new MethodParameter(method, 6);
assertTrue("Reader not supported", resolver.supportsParameter(readerParameter)); assertTrue("Reader not supported", resolver.supportsParameter(readerParameter));
@ -141,7 +142,7 @@ public class ServletRequestMethodArgumentResolverTests {
@Test @Test
public void webRequest() throws Exception { public void webRequest() throws Exception {
MethodParameter webRequestParameter = new MethodParameter(supportedParams, 7); MethodParameter webRequestParameter = new MethodParameter(method, 7);
assertTrue("WebRequest not supported", resolver.supportsParameter(webRequestParameter)); assertTrue("WebRequest not supported", resolver.supportsParameter(webRequestParameter));

View File

@ -34,24 +34,26 @@ import org.springframework.web.servlet.mvc.method.annotation.support.ServletResp
import static org.junit.Assert.*; import static org.junit.Assert.*;
/** /**
* Test fixture with {@link ServletRequestMethodArgumentResolver}.
*
* @author Arjen Poutsma * @author Arjen Poutsma
*/ */
public class ServletResponseMethodArgumentResolverTests { public class ServletResponseMethodArgumentResolverTests {
private ServletResponseMethodArgumentResolver resolver; private ServletResponseMethodArgumentResolver resolver;
private Method supportedParams; private Method method;
private ModelAndViewContainer mavContainer;
private ServletWebRequest webRequest; private ServletWebRequest webRequest;
private MockHttpServletResponse servletResponse; private MockHttpServletResponse servletResponse;
private ModelAndViewContainer mavContainer;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
resolver = new ServletResponseMethodArgumentResolver(); resolver = new ServletResponseMethodArgumentResolver();
supportedParams = getClass().getMethod("supportedParams", ServletResponse.class, OutputStream.class, Writer.class); method = getClass().getMethod("supportedParams", ServletResponse.class, OutputStream.class, Writer.class);
servletResponse = new MockHttpServletResponse(); servletResponse = new MockHttpServletResponse();
mavContainer = new ModelAndViewContainer(); mavContainer = new ModelAndViewContainer();
webRequest = new ServletWebRequest(new MockHttpServletRequest(), servletResponse); webRequest = new ServletWebRequest(new MockHttpServletRequest(), servletResponse);
@ -59,7 +61,7 @@ public class ServletResponseMethodArgumentResolverTests {
@Test @Test
public void servletResponse() throws Exception { public void servletResponse() throws Exception {
MethodParameter servletResponseParameter = new MethodParameter(supportedParams, 0); MethodParameter servletResponseParameter = new MethodParameter(method, 0);
assertTrue("ServletResponse not supported", resolver.supportsParameter(servletResponseParameter)); assertTrue("ServletResponse not supported", resolver.supportsParameter(servletResponseParameter));
@ -70,7 +72,7 @@ public class ServletResponseMethodArgumentResolverTests {
@Test @Test
public void outputStream() throws Exception { public void outputStream() throws Exception {
MethodParameter outputStreamParameter = new MethodParameter(supportedParams, 1); MethodParameter outputStreamParameter = new MethodParameter(method, 1);
assertTrue("OutputStream not supported", resolver.supportsParameter(outputStreamParameter)); assertTrue("OutputStream not supported", resolver.supportsParameter(outputStreamParameter));
@ -81,7 +83,7 @@ public class ServletResponseMethodArgumentResolverTests {
@Test @Test
public void writer() throws Exception { public void writer() throws Exception {
MethodParameter writerParameter = new MethodParameter(supportedParams, 2); MethodParameter writerParameter = new MethodParameter(method, 2);
assertTrue("Writer not supported", resolver.supportsParameter(writerParameter)); assertTrue("Writer not supported", resolver.supportsParameter(writerParameter));

View File

@ -35,7 +35,7 @@ import org.springframework.web.servlet.mvc.method.annotation.support.ViewMethodR
import org.springframework.web.servlet.view.InternalResourceView; import org.springframework.web.servlet.view.InternalResourceView;
/** /**
* Test fixture for {@link DefaultMethodReturnValueHandler} unit tests. * Test fixture with {@link DefaultMethodReturnValueHandler}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
@ -43,15 +43,15 @@ public class ViewMethodReturnValueHandlerTests {
private ViewMethodReturnValueHandler handler; private ViewMethodReturnValueHandler handler;
private ServletWebRequest webRequest;
private ModelAndViewContainer mavContainer; private ModelAndViewContainer mavContainer;
private ServletWebRequest webRequest;
@Before @Before
public void setUp() { public void setUp() {
this.handler = new ViewMethodReturnValueHandler(); handler = new ViewMethodReturnValueHandler();
this.mavContainer = new ModelAndViewContainer(new ExtendedModelMap()); mavContainer = new ModelAndViewContainer(new ExtendedModelMap());
this.webRequest = new ServletWebRequest(new MockHttpServletRequest()); webRequest = new ServletWebRequest(new MockHttpServletRequest());
} }
@Test @Test

View File

@ -93,10 +93,21 @@ public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgu
} }
/** /**
* Register the given {@link HandlerMethodArgumentResolver}. * Add the given {@link HandlerMethodArgumentResolver}.
*/ */
public void registerArgumentResolver(HandlerMethodArgumentResolver argumentResolver) { public void addResolver(HandlerMethodArgumentResolver argumentResolver) {
this.argumentResolvers.add(argumentResolver); this.argumentResolvers.add(argumentResolver);
} }
/**
* Add the given {@link HandlerMethodArgumentResolver}s.
*/
public void addResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
if (argumentResolvers != null) {
for (HandlerMethodArgumentResolver resolver : argumentResolvers) {
this.argumentResolvers.add(resolver);
}
}
}
} }

View File

@ -92,10 +92,21 @@ public class HandlerMethodReturnValueHandlerComposite implements HandlerMethodRe
} }
/** /**
* Register the given {@link HandlerMethodReturnValueHandler}. * Add the given {@link HandlerMethodReturnValueHandler}.
*/ */
public void registerReturnValueHandler(HandlerMethodReturnValueHandler returnValuehandler) { public void addHandler(HandlerMethodReturnValueHandler returnValuehandler) {
returnValueHandlers.add(returnValuehandler); returnValueHandlers.add(returnValuehandler);
} }
/**
* Add the given {@link HandlerMethodReturnValueHandler}s.
*/
public void addHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
if (returnValueHandlers != null) {
for (HandlerMethodReturnValueHandler handler : returnValueHandlers) {
this.returnValueHandlers.add(handler);
}
}
}
} }

View File

@ -23,7 +23,6 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Map; import java.util.Map;
@ -31,96 +30,96 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.beans.TestBean; import org.springframework.beans.TestBean;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.SessionAttributes; import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.DefaultSessionAttributeStore; import org.springframework.web.bind.support.DefaultSessionAttributeStore;
import org.springframework.web.bind.support.SessionAttributeStore;
import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.annotation.SessionAttributesHandler;
/** /**
* Test fixture for {@link SessionAttributesHandler} unit tests. * Test fixture with {@link SessionAttributesHandler}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
public class HandlerSessionAttributeStoreTests { public class HandlerSessionAttributeStoreTests {
private DefaultSessionAttributeStore sessionAttributes;
private SessionAttributesHandler handlerSessionAttributes;
private Class<?> handlerType = SessionAttributeHandler.class; private Class<?> handlerType = SessionAttributeHandler.class;
private SessionAttributesHandler sessionAttributesHandler;
private SessionAttributeStore sessionAttributeStore;
private NativeWebRequest request; private NativeWebRequest request;
@Before @Before
public void setUp() { public void setUp() {
this.sessionAttributes = new DefaultSessionAttributeStore(); this.sessionAttributeStore = new DefaultSessionAttributeStore();
this.handlerSessionAttributes = new SessionAttributesHandler(handlerType, sessionAttributes); this.sessionAttributesHandler = new SessionAttributesHandler(handlerType, sessionAttributeStore);
this.request = new ServletWebRequest(new MockHttpServletRequest()); this.request = new ServletWebRequest(new MockHttpServletRequest());
} }
@Test @Test
public void isSessionAttribute() throws Exception { public void isSessionAttribute() throws Exception {
assertTrue(handlerSessionAttributes.isHandlerSessionAttribute("attr1", null)); assertTrue(sessionAttributesHandler.isHandlerSessionAttribute("attr1", null));
assertTrue(handlerSessionAttributes.isHandlerSessionAttribute("attr2", null)); assertTrue(sessionAttributesHandler.isHandlerSessionAttribute("attr2", null));
assertTrue(handlerSessionAttributes.isHandlerSessionAttribute("simple", TestBean.class)); assertTrue(sessionAttributesHandler.isHandlerSessionAttribute("simple", TestBean.class));
assertFalse(sessionAttributesHandler.isHandlerSessionAttribute("simple", null));
assertFalse("Attribute name not known", handlerSessionAttributes.isHandlerSessionAttribute("simple", null));
} }
@Test @Test
public void retrieveAttributes() throws Exception { public void retrieveAttributes() throws Exception {
sessionAttributes.storeAttribute(request, "attr1", "value1"); sessionAttributeStore.storeAttribute(request, "attr1", "value1");
sessionAttributes.storeAttribute(request, "attr2", "value2"); sessionAttributeStore.storeAttribute(request, "attr2", "value2");
sessionAttributes.storeAttribute(request, "attr3", new TestBean()); sessionAttributeStore.storeAttribute(request, "attr3", new TestBean());
// Query attributes to associate them with the handler type // Resolve successfully handler session attributes once
assertTrue(handlerSessionAttributes.isHandlerSessionAttribute("attr1", null)); assertTrue(sessionAttributesHandler.isHandlerSessionAttribute("attr1", null));
assertTrue(handlerSessionAttributes.isHandlerSessionAttribute("attr3", TestBean.class)); assertTrue(sessionAttributesHandler.isHandlerSessionAttribute("attr3", TestBean.class));
Map<String, ?> attributes = handlerSessionAttributes.retrieveHandlerSessionAttributes(request); Map<String, ?> attributes = sessionAttributesHandler.retrieveHandlerSessionAttributes(request);
assertEquals(new HashSet<String>(asList("attr1", "attr3")), attributes.keySet()); assertEquals(new HashSet<String>(asList("attr1", "attr3")), attributes.keySet());
} }
@Test @Test
public void cleanupAttribute() throws Exception { public void cleanupAttributes() throws Exception {
sessionAttributes.storeAttribute(request, "attr1", "value1"); sessionAttributeStore.storeAttribute(request, "attr1", "value1");
sessionAttributes.storeAttribute(request, "attr2", "value2"); sessionAttributeStore.storeAttribute(request, "attr2", "value2");
sessionAttributes.storeAttribute(request, "attr3", new TestBean()); sessionAttributeStore.storeAttribute(request, "attr3", new TestBean());
// Query attribute to associate it with the handler type // Resolve successfully handler session attributes once
assertTrue(handlerSessionAttributes.isHandlerSessionAttribute("attr1", null)); assertTrue(sessionAttributesHandler.isHandlerSessionAttribute("attr1", null));
assertTrue(handlerSessionAttributes.isHandlerSessionAttribute("attr3", TestBean.class)); assertTrue(sessionAttributesHandler.isHandlerSessionAttribute("attr3", TestBean.class));
handlerSessionAttributes.cleanupHandlerSessionAttributes(request); sessionAttributesHandler.cleanupHandlerSessionAttributes(request);
assertNull(sessionAttributes.retrieveAttribute(request, "attr1")); assertNull(sessionAttributeStore.retrieveAttribute(request, "attr1"));
assertNotNull(sessionAttributes.retrieveAttribute(request, "attr2")); assertNotNull(sessionAttributeStore.retrieveAttribute(request, "attr2"));
assertNull(sessionAttributes.retrieveAttribute(request, "attr3")); assertNull(sessionAttributeStore.retrieveAttribute(request, "attr3"));
} }
@Test @Test
public void storeAttributes() throws Exception { public void storeAttributes() throws Exception {
Map<String, Object> attributes = new HashMap<String, Object>(); ModelMap model = new ModelMap();
attributes.put("attr1", "value1"); model.put("attr1", "value1");
attributes.put("attr2", "value2"); model.put("attr2", "value2");
attributes.put("attr3", new TestBean()); model.put("attr3", new TestBean());
// Query attribute to associate it with the handler type // Resolve successfully handler session attributes once
assertTrue(handlerSessionAttributes.isHandlerSessionAttribute("attr1", null)); assertTrue(sessionAttributesHandler.isHandlerSessionAttribute("attr1", null));
assertTrue(handlerSessionAttributes.isHandlerSessionAttribute("attr2", null)); assertTrue(sessionAttributesHandler.isHandlerSessionAttribute("attr2", null));
assertTrue(handlerSessionAttributes.isHandlerSessionAttribute("attr3", TestBean.class)); assertTrue(sessionAttributesHandler.isHandlerSessionAttribute("attr3", TestBean.class));
handlerSessionAttributes.storeHandlerSessionAttributes(request, attributes); sessionAttributesHandler.storeHandlerSessionAttributes(request, model);
assertEquals("value1", sessionAttributes.retrieveAttribute(request, "attr1")); assertEquals("value1", sessionAttributeStore.retrieveAttribute(request, "attr1"));
assertEquals("value2", sessionAttributes.retrieveAttribute(request, "attr2")); assertEquals("value2", sessionAttributeStore.retrieveAttribute(request, "attr2"));
assertTrue(sessionAttributes.retrieveAttribute(request, "attr3") instanceof TestBean); assertTrue(sessionAttributeStore.retrieveAttribute(request, "attr3") instanceof TestBean);
} }
@SessionAttributes(value = { "attr1", "attr2" }, types = { TestBean.class }) @SessionAttributes(value = { "attr1", "attr2" }, types = { TestBean.class })
private static class SessionAttributeHandler { private static class SessionAttributeHandler {
} }
} }

View File

@ -43,28 +43,28 @@ import org.springframework.web.method.support.InvocableHandlerMethod;
import org.springframework.web.method.support.HandlerMethodArgumentResolverComposite; import org.springframework.web.method.support.HandlerMethodArgumentResolverComposite;
/** /**
* Test fixture for {@link InitBinderMethodDataBinderFactory} unit tests. * Test fixture with {@link InitBinderMethodDataBinderFactory}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
public class InitBinderMethodDataBinderFactoryTests { public class InitBinderMethodDataBinderFactoryTests {
private MockHttpServletRequest request; private ConfigurableWebBindingInitializer bindingInitializer;
private HandlerMethodArgumentResolverComposite argumentResolvers;
private NativeWebRequest webRequest; private NativeWebRequest webRequest;
private ConfigurableWebBindingInitializer bindingInitializer;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
this.request = new MockHttpServletRequest(); bindingInitializer = new ConfigurableWebBindingInitializer();
this.webRequest = new ServletWebRequest(request); argumentResolvers = new HandlerMethodArgumentResolverComposite();
this.bindingInitializer = new ConfigurableWebBindingInitializer(); webRequest = new ServletWebRequest(new MockHttpServletRequest());
} }
@Test @Test
public void createBinder() throws Exception { public void createBinder() throws Exception {
InitBinderMethodDataBinderFactory factory = createFactory("initBinder", WebDataBinder.class); WebDataBinderFactory factory = createBinderFactory("initBinder", WebDataBinder.class);
WebDataBinder dataBinder = factory.createBinder(webRequest, null, null); WebDataBinder dataBinder = factory.createBinder(webRequest, null, null);
assertNotNull(dataBinder.getDisallowedFields()); assertNotNull(dataBinder.getDisallowedFields());
@ -76,7 +76,7 @@ public class InitBinderMethodDataBinderFactoryTests {
ConversionService conversionService = new DefaultFormattingConversionService(); ConversionService conversionService = new DefaultFormattingConversionService();
bindingInitializer.setConversionService(conversionService ); bindingInitializer.setConversionService(conversionService );
InitBinderMethodDataBinderFactory factory = createFactory("initBinder", WebDataBinder.class); WebDataBinderFactory factory = createBinderFactory("initBinder", WebDataBinder.class);
WebDataBinder dataBinder = factory.createBinder(webRequest, null, null); WebDataBinder dataBinder = factory.createBinder(webRequest, null, null);
assertSame(conversionService, dataBinder.getConversionService()); assertSame(conversionService, dataBinder.getConversionService());
@ -84,7 +84,7 @@ public class InitBinderMethodDataBinderFactoryTests {
@Test @Test
public void createBinderWithAttrName() throws Exception { public void createBinderWithAttrName() throws Exception {
InitBinderMethodDataBinderFactory factory = createFactory("initBinderWithAttributeName", WebDataBinder.class); WebDataBinderFactory factory = createBinderFactory("initBinderWithAttributeName", WebDataBinder.class);
WebDataBinder dataBinder = factory.createBinder(webRequest, null, "foo"); WebDataBinder dataBinder = factory.createBinder(webRequest, null, "foo");
assertNotNull(dataBinder.getDisallowedFields()); assertNotNull(dataBinder.getDisallowedFields());
@ -93,7 +93,7 @@ public class InitBinderMethodDataBinderFactoryTests {
@Test @Test
public void createBinderWithAttrNameNoMatch() throws Exception { public void createBinderWithAttrNameNoMatch() throws Exception {
WebDataBinderFactory factory = createFactory("initBinderWithAttributeName", WebDataBinder.class); WebDataBinderFactory factory = createBinderFactory("initBinderWithAttributeName", WebDataBinder.class);
WebDataBinder dataBinder = factory.createBinder(webRequest, null, "invalidName"); WebDataBinder dataBinder = factory.createBinder(webRequest, null, "invalidName");
assertNull(dataBinder.getDisallowedFields()); assertNull(dataBinder.getDisallowedFields());
@ -101,41 +101,34 @@ public class InitBinderMethodDataBinderFactoryTests {
@Test(expected=IllegalStateException.class) @Test(expected=IllegalStateException.class)
public void returnValueNotExpected() throws Exception { public void returnValueNotExpected() throws Exception {
WebDataBinderFactory factory = createFactory("initBinderReturnValue", WebDataBinder.class); WebDataBinderFactory factory = createBinderFactory("initBinderReturnValue", WebDataBinder.class);
factory.createBinder(webRequest, null, "invalidName"); factory.createBinder(webRequest, null, "invalidName");
} }
@Test @Test
public void createBinderTypeConversion() throws Exception { public void createBinderTypeConversion() throws Exception {
request.setParameter("requestParam", "22"); webRequest.getNativeRequest(MockHttpServletRequest.class).setParameter("requestParam", "22");
argumentResolvers.addResolver(new RequestParamMethodArgumentResolver(null, false));
HandlerMethodArgumentResolverComposite argResolvers = new HandlerMethodArgumentResolverComposite(); WebDataBinderFactory factory = createBinderFactory("initBinderTypeConversion", WebDataBinder.class, int.class);
argResolvers.registerArgumentResolver(new RequestParamMethodArgumentResolver(null, false));
String methodName = "initBinderTypeConversion";
WebDataBinderFactory factory = createFactory(argResolvers, methodName, WebDataBinder.class, int.class);
WebDataBinder dataBinder = factory.createBinder(webRequest, null, "foo"); WebDataBinder dataBinder = factory.createBinder(webRequest, null, "foo");
assertNotNull(dataBinder.getDisallowedFields()); assertNotNull(dataBinder.getDisallowedFields());
assertEquals("requestParam-22", dataBinder.getDisallowedFields()[0]); assertEquals("requestParam-22", dataBinder.getDisallowedFields()[0]);
} }
private InitBinderMethodDataBinderFactory createFactory(String methodName, Class<?>... parameterTypes) private WebDataBinderFactory createBinderFactory(String methodName, Class<?>... parameterTypes)
throws Exception { throws Exception {
return createFactory(new HandlerMethodArgumentResolverComposite(), methodName, parameterTypes);
}
private InitBinderMethodDataBinderFactory createFactory(HandlerMethodArgumentResolverComposite argResolvers,
String methodName, Class<?>... parameterTypes) throws Exception {
Object handler = new InitBinderHandler(); Object handler = new InitBinderHandler();
Method method = InitBinderHandler.class.getMethod(methodName, parameterTypes); Method method = handler.getClass().getMethod(methodName, parameterTypes);
InvocableHandlerMethod controllerMethod = new InvocableHandlerMethod(handler, method); InvocableHandlerMethod handlerMethod = new InvocableHandlerMethod(handler, method);
controllerMethod.setHandlerMethodArgumentResolvers(argResolvers); handlerMethod.setHandlerMethodArgumentResolvers(argumentResolvers);
controllerMethod.setDataBinderFactory(new DefaultDataBinderFactory(null)); handlerMethod.setDataBinderFactory(new DefaultDataBinderFactory(null));
controllerMethod.setParameterNameDiscoverer(new LocalVariableTableParameterNameDiscoverer()); handlerMethod.setParameterNameDiscoverer(new LocalVariableTableParameterNameDiscoverer());
return new InitBinderMethodDataBinderFactory(Arrays.asList(controllerMethod), bindingInitializer); return new InitBinderMethodDataBinderFactory(Arrays.asList(handlerMethod), bindingInitializer);
} }
private static class InitBinderHandler { private static class InitBinderHandler {

View File

@ -49,87 +49,91 @@ import org.springframework.web.method.support.InvocableHandlerMethod;
import org.springframework.web.method.support.ModelAndViewContainer; import org.springframework.web.method.support.ModelAndViewContainer;
/** /**
* Text fixture for {@link ModelFactory} unit tests. * Text fixture for {@link ModelFactory} tests.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
public class ModelFactoryTests { public class ModelFactoryTests {
private NativeWebRequest webRequest; private Object handler = new ModelHandler();
private SessionAttributeStore sessionAttributeStore; private InvocableHandlerMethod handleMethod;
private SessionAttributesHandler handlerSessionAttributeStore; private SessionAttributesHandler handlerSessionAttributeStore;
private InvocableHandlerMethod requestMethod; private SessionAttributeStore sessionAttributeStore;
private ModelAndViewContainer mavContainer; private ModelAndViewContainer mavContainer;
private NativeWebRequest webRequest;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
Object handler = new ModelHandler(); handleMethod = new InvocableHandlerMethod(handler, handler.getClass().getDeclaredMethod("handle"));
Method method = handler.getClass().getDeclaredMethod("handle"); sessionAttributeStore = new DefaultSessionAttributeStore();
this.requestMethod = new InvocableHandlerMethod(handler, method); handlerSessionAttributeStore = new SessionAttributesHandler(handler.getClass(), sessionAttributeStore);
mavContainer = new ModelAndViewContainer();
this.sessionAttributeStore = new DefaultSessionAttributeStore(); webRequest = new ServletWebRequest(new MockHttpServletRequest());
this.handlerSessionAttributeStore = new SessionAttributesHandler(handler.getClass(), sessionAttributeStore);
this.mavContainer = new ModelAndViewContainer();
this.webRequest = new ServletWebRequest(new MockHttpServletRequest());
} }
@Test @Test
public void createModel() throws Exception { public void createModel() throws Exception {
createFactory(new ModelHandler(), "model", Model.class).initModel(webRequest, mavContainer, requestMethod); ModelFactory modelFactory = createModelFactory("model", Model.class);
modelFactory.initModel(webRequest, mavContainer, handleMethod);
assertEquals(Boolean.TRUE, mavContainer.getAttribute("model")); assertEquals(Boolean.TRUE, mavContainer.getAttribute("model"));
} }
@Test @Test
public void createModelWithName() throws Exception { public void createModelWithName() throws Exception {
createFactory(new ModelHandler(), "modelWithName").initModel(webRequest, mavContainer, requestMethod); ModelFactory modelFactory = createModelFactory("modelWithName");
modelFactory.initModel(webRequest, mavContainer, handleMethod);
assertEquals(Boolean.TRUE, mavContainer.getAttribute("name")); assertEquals(Boolean.TRUE, mavContainer.getAttribute("name"));
} }
@Test @Test
public void createModelWithDefaultName() throws Exception { public void createModelWithDefaultName() throws Exception {
createFactory(new ModelHandler(), "modelWithDefaultName").initModel(webRequest, mavContainer, requestMethod); ModelFactory modelFactory = createModelFactory("modelWithDefaultName");
modelFactory.initModel(webRequest, mavContainer, handleMethod);
assertEquals(Boolean.TRUE, mavContainer.getAttribute("boolean")); assertEquals(Boolean.TRUE, mavContainer.getAttribute("boolean"));
} }
@Test @Test
public void createModelWithExistingName() throws Exception { public void createModelWithExistingName() throws Exception {
createFactory(new ModelHandler(), "modelWithName").initModel(webRequest, mavContainer, requestMethod); ModelFactory modelFactory = createModelFactory("modelWithName");
modelFactory.initModel(webRequest, mavContainer, handleMethod);
assertEquals(Boolean.TRUE, mavContainer.getAttribute("name")); assertEquals(Boolean.TRUE, mavContainer.getAttribute("name"));
} }
@Test @Test
public void createModelWithNullAttribute() throws Exception { public void createModelWithNullAttribute() throws Exception {
createFactory(new ModelHandler(), "modelWithNullAttribute").initModel(webRequest, mavContainer, requestMethod); ModelFactory modelFactory = createModelFactory("modelWithNullAttribute");
modelFactory.initModel(webRequest, mavContainer, handleMethod);
assertTrue(mavContainer.containsAttribute("name")); assertTrue(mavContainer.containsAttribute("name"));
assertNull(mavContainer.getAttribute("name")); assertNull(mavContainer.getAttribute("name"));
} }
@Test @Test
public void createModelExistingSessionAttributes() throws Exception { public void createModelExistingSessionAttributes() throws Exception {
sessionAttributeStore.storeAttribute(webRequest, "sessionAttr", "sessionAttrValue"); sessionAttributeStore.storeAttribute(webRequest, "sessAttr", "sessAttrValue");
// Query attribute to associate it with the handler type // Resolve successfully handler session attribute once
assertTrue(handlerSessionAttributeStore.isHandlerSessionAttribute("sessionAttr", null)); assertTrue(handlerSessionAttributeStore.isHandlerSessionAttribute("sessAttr", null));
createFactory(new ModelHandler(), "model", Model.class).initModel(webRequest, mavContainer, requestMethod); ModelFactory modelFactory = createModelFactory("model", Model.class);
assertEquals("sessionAttrValue", mavContainer.getAttribute("sessionAttr")); modelFactory.initModel(webRequest, mavContainer, handleMethod);
assertEquals("sessAttrValue", mavContainer.getAttribute("sessAttr"));
} }
@Test @Test
public void updateBindingResult() throws Exception { public void updateBindingResult() throws Exception {
Object handler = new ModelHandler();
SessionAttributeStore store = new DefaultSessionAttributeStore();
SessionAttributesHandler sessionAttributeStore = new SessionAttributesHandler(handler.getClass(), store);
String attrName = "attr1"; String attrName = "attr1";
Object attrValue = new Object(); Object attrValue = new Object();
mavContainer.addAttribute(attrName, attrValue); mavContainer.addAttribute(attrName, attrValue);
WebDataBinder dataBinder = new WebDataBinder(attrValue, attrName); WebDataBinder dataBinder = new WebDataBinder(attrValue, attrName);
@ -138,7 +142,7 @@ public class ModelFactoryTests {
expect(binderFactory.createBinder(webRequest, attrValue, attrName)).andReturn(dataBinder); expect(binderFactory.createBinder(webRequest, attrValue, attrName)).andReturn(dataBinder);
replay(binderFactory); replay(binderFactory);
ModelFactory modelFactory = new ModelFactory(null, binderFactory, sessionAttributeStore); ModelFactory modelFactory = new ModelFactory(null, binderFactory, handlerSessionAttributeStore);
modelFactory.updateModel(webRequest, mavContainer, new SimpleSessionStatus()); modelFactory.updateModel(webRequest, mavContainer, new SimpleSessionStatus());
assertEquals(attrValue, mavContainer.getModel().remove(attrName)); assertEquals(attrValue, mavContainer.getModel().remove(attrName));
@ -152,21 +156,21 @@ public class ModelFactoryTests {
return BindingResult.MODEL_KEY_PREFIX + key; return BindingResult.MODEL_KEY_PREFIX + key;
} }
private ModelFactory createFactory(Object handler, String methodName, Class<?>... parameterTypes) throws Exception{ private ModelFactory createModelFactory(String methodName, Class<?>... parameterTypes) throws Exception{
Method method = ModelHandler.class.getMethod(methodName, parameterTypes); Method method = ModelHandler.class.getMethod(methodName, parameterTypes);
HandlerMethodArgumentResolverComposite argResolvers = new HandlerMethodArgumentResolverComposite(); HandlerMethodArgumentResolverComposite argResolvers = new HandlerMethodArgumentResolverComposite();
argResolvers.registerArgumentResolver(new ModelMethodProcessor()); argResolvers.addResolver(new ModelMethodProcessor());
InvocableHandlerMethod controllerMethod = new InvocableHandlerMethod(handler, method); InvocableHandlerMethod handlerMethod = new InvocableHandlerMethod(handler, method);
controllerMethod.setHandlerMethodArgumentResolvers(argResolvers); handlerMethod.setHandlerMethodArgumentResolvers(argResolvers);
controllerMethod.setDataBinderFactory(null); handlerMethod.setDataBinderFactory(null);
controllerMethod.setParameterNameDiscoverer(new LocalVariableTableParameterNameDiscoverer()); handlerMethod.setParameterNameDiscoverer(new LocalVariableTableParameterNameDiscoverer());
return new ModelFactory(Arrays.asList(controllerMethod), null, handlerSessionAttributeStore); return new ModelFactory(Arrays.asList(handlerMethod), null, handlerSessionAttributeStore);
} }
@SessionAttributes("sessionAttr") @SessionAttributes("sessAttr")
private static class ModelHandler { private static class ModelHandler {
@SuppressWarnings("unused") @SuppressWarnings("unused")

View File

@ -0,0 +1,109 @@
/*
* 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.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.NativeWebRequest;
import org.springframework.web.context.request.ServletWebRequest;
/**
* Test fixture with {@link AbstractCookieValueMethodArgumentResolver}.
*
* @author Arjen Poutsma
* @author Rossen Stoyanchev
*/
public class CookieValueMethodArgumentResolverTests {
private AbstractCookieValueMethodArgumentResolver resolver;
private MethodParameter paramNamedCookie;
private MethodParameter paramNamedDefaultValueString;
private MethodParameter paramString;
private ServletWebRequest webRequest;
private MockHttpServletRequest request;
@Before
public void setUp() throws Exception {
resolver = new TestCookieValueMethodArgumentResolver();
Method method = getClass().getMethod("params", Cookie.class, String.class, String.class);
paramNamedCookie = new MethodParameter(method, 0);
paramNamedDefaultValueString = new MethodParameter(method, 1);
paramString = new MethodParameter(method, 2);
request = new MockHttpServletRequest();
webRequest = new ServletWebRequest(request, new MockHttpServletResponse());
}
@Test
public void supportsParameter() {
assertTrue("Cookie parameter not supported", resolver.supportsParameter(paramNamedCookie));
assertTrue("Cookie string parameter not supported", resolver.supportsParameter(paramNamedDefaultValueString));
assertFalse("non-@CookieValue parameter supported", resolver.supportsParameter(paramString));
}
@Test
public void resolveCookieDefaultValue() throws Exception {
Object result = resolver.resolveArgument(paramNamedDefaultValueString, null, webRequest, null);
assertTrue(result instanceof String);
assertEquals("Invalid result", "bar", result);
}
@Test(expected = IllegalStateException.class)
public void notFound() throws Exception {
Object result = resolver.resolveArgument(paramNamedCookie, null, webRequest, null);
assertTrue(result instanceof String);
assertEquals("Invalid result", "bar", result);
}
private static class TestCookieValueMethodArgumentResolver extends AbstractCookieValueMethodArgumentResolver {
public TestCookieValueMethodArgumentResolver() {
super(null);
}
@Override
protected Object resolveName(String name, MethodParameter parameter, NativeWebRequest request) throws Exception {
return null;
}
}
public void params(@CookieValue("name") Cookie param1,
@CookieValue(value = "name", defaultValue = "bar") String param2,
String param3) {
}
}

View File

@ -18,8 +18,6 @@ package org.springframework.web.method.annotation.support;
import static org.junit.Assert.assertSame; import static org.junit.Assert.assertSame;
import java.lang.reflect.Method;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
@ -32,88 +30,59 @@ import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.support.ModelAndViewContainer; import org.springframework.web.method.support.ModelAndViewContainer;
/** /**
* Test fixture for {@link ErrorsMethodArgumentResolver} unit tests. * Test fixture with {@link ErrorsMethodArgumentResolver}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
public class ErrorsMethodHandlerArgumentResolverTests { public class ErrorsMethodHandlerArgumentResolverTests {
private final ErrorsMethodArgumentResolver resolver = new ErrorsMethodArgumentResolver();
private BindingResult bindingResult;
private MethodParameter paramErrors;
private NativeWebRequest webRequest; private NativeWebRequest webRequest;
private ErrorsMethodArgumentResolver resolver;
private MethodParameter errorsParam;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
this.webRequest = new ServletWebRequest(new MockHttpServletRequest()); paramErrors = new MethodParameter(getClass().getDeclaredMethod("handle", Errors.class), 0);
bindingResult = new WebDataBinder(new Object(), "attr").getBindingResult();
this.resolver = new ErrorsMethodArgumentResolver(); webRequest = new ServletWebRequest(new MockHttpServletRequest());
Method method = this.getClass().getDeclaredMethod("handle", Errors.class);
this.errorsParam = new MethodParameter(method, 0);
} }
@Test @Test
public void supports() throws Exception { public void supports() throws Exception {
resolver.supportsParameter(errorsParam); resolver.supportsParameter(paramErrors);
} }
@Test @Test
public void bindingResult() throws Exception { public void bindingResult() throws Exception {
WebDataBinder dataBinder = new WebDataBinder(new Object(), "attr");
BindingResult bindingResult = dataBinder.getBindingResult();
ModelAndViewContainer mavContainer = new ModelAndViewContainer(); ModelAndViewContainer mavContainer = new ModelAndViewContainer();
mavContainer.addAttribute("ignore1", "value1"); mavContainer.addAttribute("ignore1", "value1");
mavContainer.addAttribute("ignore2", "value2"); mavContainer.addAttribute("ignore2", "value2");
mavContainer.addAttribute("ignore3", "value3"); mavContainer.addAttribute("ignore3", "value3");
mavContainer.addAttribute("ignore4", "value4"); mavContainer.addAttribute("ignore4", "value4");
mavContainer.addAttribute("ignore5", "value5"); mavContainer.addAttribute("ignore5", "value5");
mavContainer.addAllAttributes(bindingResult.getModel()); // Predictable iteration order of model keys important! mavContainer.addAllAttributes(bindingResult.getModel());
Object actual = resolver.resolveArgument(errorsParam, mavContainer, webRequest, null); Object actual = resolver.resolveArgument(paramErrors, mavContainer, webRequest, null);
assertSame(actual, bindingResult); assertSame(actual, bindingResult);
} }
@Test
public void bindingResultExistingModelAttribute() throws Exception {
Object target1 = new Object();
WebDataBinder binder1 = new WebDataBinder(target1, "attr1");
BindingResult bindingResult1 = binder1.getBindingResult();
Object target2 = new Object();
WebDataBinder binder2 = new WebDataBinder(target1, "attr2");
BindingResult bindingResult2 = binder2.getBindingResult();
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
mavContainer.addAttribute("attr1", target1);
mavContainer.addAttribute("attr2", target2);
mavContainer.addAttribute("filler", "fillerValue");
mavContainer.addAllAttributes(bindingResult1.getModel());
mavContainer.addAllAttributes(bindingResult2.getModel());
Object actual = resolver.resolveArgument(errorsParam, mavContainer, webRequest, null);
assertSame("Should resolve to the latest BindingResult added", actual, bindingResult2);
}
@Test(expected=IllegalStateException.class) @Test(expected=IllegalStateException.class)
public void bindingResultNotFound() throws Exception { public void bindingResultNotFound() throws Exception {
WebDataBinder dataBinder = new WebDataBinder(new Object(), "attr");
BindingResult bindingResult = dataBinder.getBindingResult();
ModelAndViewContainer mavContainer = new ModelAndViewContainer(); ModelAndViewContainer mavContainer = new ModelAndViewContainer();
mavContainer.addAllAttributes(bindingResult.getModel()); mavContainer.addAllAttributes(bindingResult.getModel());
mavContainer.addAttribute("ignore1", "value1"); mavContainer.addAttribute("ignore1", "value1");
resolver.resolveArgument(errorsParam, mavContainer, webRequest, null); resolver.resolveArgument(paramErrors, mavContainer, webRequest, null);
} }
@Test(expected=IllegalStateException.class) @Test(expected=IllegalStateException.class)
public void noBindingResult() throws Exception { public void noBindingResult() throws Exception {
resolver.resolveArgument(errorsParam, new ModelAndViewContainer(), webRequest, null); resolver.resolveArgument(paramErrors, new ModelAndViewContainer(), webRequest, null);
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")

View File

@ -36,7 +36,7 @@ import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.method.annotation.support.ExpressionValueMethodArgumentResolver; import org.springframework.web.method.annotation.support.ExpressionValueMethodArgumentResolver;
/** /**
* Test fixture for {@link ExpressionValueMethodArgumentResolver} unit tests. * Test fixture with {@link ExpressionValueMethodArgumentResolver}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
@ -44,13 +44,11 @@ public class ExpressionValueMethodArgumentResolverTests {
private ExpressionValueMethodArgumentResolver resolver; private ExpressionValueMethodArgumentResolver resolver;
private MethodParameter systemParameter; private MethodParameter paramSystemProperty;
private MethodParameter requestParameter; private MethodParameter paramContextPath;
private MethodParameter unsupported; private MethodParameter paramNotSupported;
private MockHttpServletRequest servletRequest;
private NativeWebRequest webRequest; private NativeWebRequest webRequest;
@ -58,16 +56,14 @@ public class ExpressionValueMethodArgumentResolverTests {
public void setUp() throws Exception { public void setUp() throws Exception {
GenericWebApplicationContext context = new GenericWebApplicationContext(); GenericWebApplicationContext context = new GenericWebApplicationContext();
context.refresh(); context.refresh();
resolver = new ExpressionValueMethodArgumentResolver(context.getBeanFactory()); resolver = new ExpressionValueMethodArgumentResolver(context.getBeanFactory());
Method method = getClass().getMethod("params", int.class, String.class, String.class); Method method = getClass().getMethod("params", int.class, String.class, String.class);
systemParameter = new MethodParameter(method, 0); paramSystemProperty = new MethodParameter(method, 0);
requestParameter = new MethodParameter(method, 1); paramContextPath = new MethodParameter(method, 1);
unsupported = new MethodParameter(method, 2); paramNotSupported = new MethodParameter(method, 2);
servletRequest = new MockHttpServletRequest(); webRequest = new ServletWebRequest(new MockHttpServletRequest(), new MockHttpServletResponse());
webRequest = new ServletWebRequest(servletRequest, new MockHttpServletResponse());
// Expose request to the current thread (for SpEL expressions) // Expose request to the current thread (for SpEL expressions)
RequestContextHolder.setRequestAttributes(webRequest); RequestContextHolder.setRequestAttributes(webRequest);
@ -80,31 +76,31 @@ public class ExpressionValueMethodArgumentResolverTests {
@Test @Test
public void supportsParameter() throws Exception { public void supportsParameter() throws Exception {
assertTrue(resolver.supportsParameter(systemParameter)); assertTrue(resolver.supportsParameter(paramSystemProperty));
assertTrue(resolver.supportsParameter(requestParameter)); assertTrue(resolver.supportsParameter(paramContextPath));
assertFalse(resolver.supportsParameter(paramNotSupported));
assertFalse(resolver.supportsParameter(unsupported));
} }
@Test @Test
public void resolveSystemProperty() throws Exception { public void resolveSystemProperty() throws Exception {
System.setProperty("systemIntValue", "22"); System.setProperty("systemProperty", "22");
Object value = resolver.resolveArgument(systemParameter, null, webRequest, null); Object value = resolver.resolveArgument(paramSystemProperty, null, webRequest, null);
System.clearProperty("systemProperty");
assertEquals("22", value); assertEquals("22", value);
} }
@Test @Test
public void resolveRequestProperty() throws Exception { public void resolveContextPath() throws Exception {
servletRequest.setContextPath("/contextPath"); webRequest.getNativeRequest(MockHttpServletRequest.class).setContextPath("/contextPath");
Object value = resolver.resolveArgument(requestParameter, null, webRequest, null); Object value = resolver.resolveArgument(paramContextPath, null, webRequest, null);
assertEquals("/contextPath", value); assertEquals("/contextPath", value);
} }
public void params(@Value("#{systemProperties.systemIntValue}") int param1, public void params(@Value("#{systemProperties.systemProperty}") int param1,
@Value("#{request.contextPath}") String param2, @Value("#{request.contextPath}") String param2,
String unsupported) { String notSupported) {
} }
} }

View File

@ -55,7 +55,7 @@ import org.springframework.web.context.request.WebRequest;
import org.springframework.web.method.support.ModelAndViewContainer; import org.springframework.web.method.support.ModelAndViewContainer;
/** /**
* Test fixture for {@link ModelAttributeMethodProcessor} unit tests. * Test fixture with {@link ModelAttributeMethodProcessor}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
@ -63,17 +63,19 @@ public class ModelAttributeMethodProcessorTests {
private ModelAttributeMethodProcessor processor; private ModelAttributeMethodProcessor processor;
private MethodParameter annotatedParam; private MethodParameter paramNamedValidModelAttr;
private MethodParameter integerParam; private MethodParameter paramErrors;
private MethodParameter defaultNameParam; private MethodParameter paramInt;
private MethodParameter notAnnotatedParam; private MethodParameter paramModelAttr;
private MethodParameter annotatedReturnParam; private MethodParameter paramNonSimpleType;
private MethodParameter notAnnotatedReturnParam; private MethodParameter returnParamNamedModelAttr;
private MethodParameter returnParamNonSimpleType;
private ModelAndViewContainer mavContainer; private ModelAndViewContainer mavContainer;
@ -81,66 +83,77 @@ public class ModelAttributeMethodProcessorTests {
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
this.processor = new ModelAttributeMethodProcessor(true); processor = new ModelAttributeMethodProcessor(true);
Class<?> handlerType = ModelAttributeHandler.class; Method method = ModelAttributeHandler.class.getDeclaredMethod("modelAttribute",
Method method = handlerType.getDeclaredMethod("modelAttribute", TestBean.class, Errors.class, int.class, TestBean.class, Errors.class, int.class, TestBean.class, TestBean.class);
TestBean.class, TestBean.class);
this.annotatedParam = new MethodParameter(method, 0); paramNamedValidModelAttr = new MethodParameter(method, 0);
this.integerParam = new MethodParameter(method, 2); paramErrors = new MethodParameter(method, 1);
this.defaultNameParam = new MethodParameter(method, 3); paramInt = new MethodParameter(method, 2);
this.notAnnotatedParam = new MethodParameter(method, 4); paramModelAttr = new MethodParameter(method, 3);
paramNonSimpleType = new MethodParameter(method, 4);
this.annotatedReturnParam = new MethodParameter(getClass().getDeclaredMethod("annotatedReturnValue"), -1); returnParamNamedModelAttr = new MethodParameter(getClass().getDeclaredMethod("annotatedReturnValue"), -1);
this.notAnnotatedReturnParam = new MethodParameter(getClass().getDeclaredMethod("notAnnotatedReturnValue"), -1); returnParamNonSimpleType = new MethodParameter(getClass().getDeclaredMethod("notAnnotatedReturnValue"), -1);
mavContainer = new ModelAndViewContainer(); mavContainer = new ModelAndViewContainer();
this.webRequest = new ServletWebRequest(new MockHttpServletRequest()); webRequest = new ServletWebRequest(new MockHttpServletRequest());
} }
@Test @Test
public void supportParameter() throws Exception { public void supportParameter() throws Exception {
assertTrue(processor.supportsParameter(annotatedParam)); processor = new ModelAttributeMethodProcessor(true);
assertFalse(processor.supportsParameter(integerParam)); assertTrue(processor.supportsParameter(paramNamedValidModelAttr));
assertTrue(processor.supportsParameter(notAnnotatedParam)); assertTrue(processor.supportsParameter(paramErrors));
assertFalse(processor.supportsParameter(paramInt));
assertTrue(processor.supportsParameter(paramModelAttr));
assertTrue(processor.supportsParameter(paramNonSimpleType));
this.processor = new ModelAttributeMethodProcessor(false); processor = new ModelAttributeMethodProcessor(false);
assertFalse(processor.supportsParameter(notAnnotatedParam)); assertTrue(processor.supportsParameter(paramNamedValidModelAttr));
assertFalse(processor.supportsParameter(paramErrors));
assertFalse(processor.supportsParameter(paramInt));
assertTrue(processor.supportsParameter(paramModelAttr));
assertFalse(processor.supportsParameter(paramNonSimpleType));
} }
@Test @Test
public void supportsReturnType() throws Exception { public void supportsReturnType() throws Exception {
assertTrue(processor.supportsReturnType(annotatedReturnParam)); processor = new ModelAttributeMethodProcessor(true);
assertFalse(processor.supportsReturnType(notAnnotatedReturnParam)); assertTrue(processor.supportsReturnType(returnParamNamedModelAttr));
assertFalse(processor.supportsReturnType(returnParamNonSimpleType));
processor = new ModelAttributeMethodProcessor(false);
assertTrue(processor.supportsReturnType(returnParamNamedModelAttr));
assertFalse(processor.supportsReturnType(returnParamNonSimpleType));
} }
@Test @Test
public void shouldValidate() throws Exception { public void shouldValidate() throws Exception {
assertTrue(processor.shouldValidate(annotatedParam)); assertTrue(processor.shouldValidate(paramNamedValidModelAttr));
assertFalse(processor.shouldValidate(notAnnotatedParam)); assertFalse(processor.shouldValidate(paramNonSimpleType));
} }
@Test @Test
public void failOnError() throws Exception { public void failOnError() throws Exception {
assertFalse(processor.failOnError(annotatedParam)); assertFalse("Shouldn't failOnError with BindingResult", processor.failOnError(paramNamedValidModelAttr));
assertTrue(processor.failOnError(notAnnotatedParam)); assertTrue("Should failOnError without BindingResult", processor.failOnError(paramNonSimpleType));
} }
@Test @Test
public void createBinderFromModelAttribute() throws Exception { public void createBinderFromModelAttribute() throws Exception {
createBinderFromModelAttr("attrName", annotatedParam); createBinderFromModelAttr("attrName", paramNamedValidModelAttr);
createBinderFromModelAttr("testBean", defaultNameParam); createBinderFromModelAttr("testBean", paramModelAttr);
createBinderFromModelAttr("testBean", notAnnotatedParam); createBinderFromModelAttr("testBean", paramNonSimpleType);
} }
private void createBinderFromModelAttr(String expectedAttrName, MethodParameter param) throws Exception { private void createBinderFromModelAttr(String expectedAttrName, MethodParameter param) throws Exception {
Object target = new TestBean(); Object target = new TestBean();
mavContainer.addAttribute(expectedAttrName, target); mavContainer.addAttribute(expectedAttrName, target);
WebDataBinder dataBinder = new WebRequestDataBinder(null); WebDataBinder dataBinder = new WebRequestDataBinder(target);
WebDataBinderFactory binderFactory = createMock(WebDataBinderFactory.class); WebDataBinderFactory binderFactory = createMock(WebDataBinderFactory.class);
expect(binderFactory.createBinder(webRequest, target, expectedAttrName)).andReturn(dataBinder); expect(binderFactory.createBinder(webRequest, target, expectedAttrName)).andReturn(dataBinder);
replay(binderFactory); replay(binderFactory);
@ -158,7 +171,7 @@ public class ModelAttributeMethodProcessorTests {
expect(factory.createBinder((NativeWebRequest) anyObject(), notNull(), eq("attrName"))).andReturn(dataBinder); expect(factory.createBinder((NativeWebRequest) anyObject(), notNull(), eq("attrName"))).andReturn(dataBinder);
replay(factory); replay(factory);
processor.resolveArgument(annotatedParam, mavContainer, webRequest, factory); processor.resolveArgument(paramNamedValidModelAttr, mavContainer, webRequest, factory);
verify(factory); verify(factory);
} }
@ -167,13 +180,13 @@ public class ModelAttributeMethodProcessorTests {
public void bindAndValidate() throws Exception { public void bindAndValidate() throws Exception {
Object target = new TestBean(); Object target = new TestBean();
mavContainer.addAttribute("attrName", target); mavContainer.addAttribute("attrName", target);
StubRequestDataBinder dataBinder = new StubRequestDataBinder(target);
StubRequestDataBinder dataBinder = new StubRequestDataBinder(target);
WebDataBinderFactory binderFactory = createMock(WebDataBinderFactory.class); WebDataBinderFactory binderFactory = createMock(WebDataBinderFactory.class);
expect(binderFactory.createBinder(webRequest, target, "attrName")).andReturn(dataBinder); expect(binderFactory.createBinder(webRequest, target, "attrName")).andReturn(dataBinder);
replay(binderFactory); replay(binderFactory);
processor.resolveArgument(annotatedParam, mavContainer, webRequest, binderFactory); processor.resolveArgument(paramNamedValidModelAttr, mavContainer, webRequest, binderFactory);
assertTrue(dataBinder.isBindInvoked()); assertTrue(dataBinder.isBindInvoked());
assertTrue(dataBinder.isValidateInvoked()); assertTrue(dataBinder.isValidateInvoked());
@ -183,6 +196,7 @@ public class ModelAttributeMethodProcessorTests {
public void bindAndFail() throws Exception { public void bindAndFail() throws Exception {
Object target = new TestBean(); Object target = new TestBean();
mavContainer.getModel().addAttribute(target); mavContainer.getModel().addAttribute(target);
StubRequestDataBinder dataBinder = new StubRequestDataBinder(target); StubRequestDataBinder dataBinder = new StubRequestDataBinder(target);
dataBinder.getBindingResult().reject("error"); dataBinder.getBindingResult().reject("error");
@ -190,50 +204,23 @@ public class ModelAttributeMethodProcessorTests {
expect(binderFactory.createBinder(webRequest, target, "testBean")).andReturn(dataBinder); expect(binderFactory.createBinder(webRequest, target, "testBean")).andReturn(dataBinder);
replay(binderFactory); replay(binderFactory);
processor.resolveArgument(notAnnotatedParam, mavContainer, webRequest, binderFactory); processor.resolveArgument(paramNonSimpleType, mavContainer, webRequest, binderFactory);
} }
@Test @Test
public void handleAnnotatedReturnValue() throws Exception { public void handleAnnotatedReturnValue() throws Exception {
ModelAndViewContainer mavContainer = new ModelAndViewContainer(); processor.handleReturnValue("expected", returnParamNamedModelAttr, mavContainer, webRequest);
processor.handleReturnValue("expected", annotatedReturnParam, mavContainer, webRequest);
assertEquals("expected", mavContainer.getModel().get("modelAttrName")); assertEquals("expected", mavContainer.getModel().get("modelAttrName"));
} }
@Test @Test
public void handleNotAnnotatedReturnValue() throws Exception { public void handleNotAnnotatedReturnValue() throws Exception {
TestBean testBean = new TestBean("expected"); TestBean testBean = new TestBean("expected");
ModelAndViewContainer mavContainer = new ModelAndViewContainer(); processor.handleReturnValue(testBean, returnParamNonSimpleType, mavContainer, webRequest);
processor.handleReturnValue(testBean, notAnnotatedReturnParam, mavContainer, webRequest);
assertSame(testBean, mavContainer.getModel().get("testBean")); assertSame(testBean, mavContainer.getModel().get("testBean"));
} }
@SessionAttributes(types=TestBean.class)
private static class ModelAttributeHandler {
@SuppressWarnings("unused")
public void modelAttribute(@ModelAttribute("attrName") @Valid TestBean annotatedAttr,
Errors errors,
int intArg,
@ModelAttribute TestBean defaultNameAttr,
TestBean notAnnotatedAttr) {
}
}
@SuppressWarnings("unused")
@ModelAttribute("modelAttrName")
private String annotatedReturnValue() {
return null;
}
@SuppressWarnings("unused")
private TestBean notAnnotatedReturnValue() {
return null;
}
private static class StubRequestDataBinder extends WebRequestDataBinder { private static class StubRequestDataBinder extends WebRequestDataBinder {
private boolean bindInvoked; private boolean bindInvoked;
@ -252,14 +239,12 @@ public class ModelAttributeMethodProcessorTests {
return validateInvoked; return validateInvoked;
} }
@Override
public void bind(WebRequest request) { public void bind(WebRequest request) {
this.bindInvoked = true; bindInvoked = true;
} }
@Override
public void validate() { public void validate() {
this.validateInvoked = true; validateInvoked = true;
} }
} }
@ -268,4 +253,26 @@ public class ModelAttributeMethodProcessorTests {
public @interface Valid { public @interface Valid {
} }
@SessionAttributes(types=TestBean.class)
private static class ModelAttributeHandler {
@SuppressWarnings("unused")
public void modelAttribute(@ModelAttribute("attrName") @Valid TestBean annotatedAttr,
Errors errors,
int intArg,
@ModelAttribute TestBean defaultNameAttr,
TestBean notAnnotatedAttr) {
}
}
@SuppressWarnings("unused")
@ModelAttribute("modelAttrName")
private String annotatedReturnValue() {
return null;
}
@SuppressWarnings("unused")
private TestBean notAnnotatedReturnValue() {
return null;
}
} }

View File

@ -27,7 +27,6 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.request.NativeWebRequest;
@ -35,81 +34,83 @@ import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.support.ModelAndViewContainer; import org.springframework.web.method.support.ModelAndViewContainer;
/** /**
* Test fixture for {@link ModelMethodProcessor} unit tests. * Test fixture with {@link ModelMethodProcessor}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
public class ModelMethodProcessorTests { public class ModelMethodProcessorTests {
private ModelMethodProcessor resolver; private ModelMethodProcessor processor;
private MethodParameter modelParameter; private ModelAndViewContainer mavContainer;
private MethodParameter modelReturnType; private MethodParameter paramModel;
private MethodParameter mapParameter; private MethodParameter returnParamModel;
private MethodParameter mapReturnType; private MethodParameter paramMap;
private MethodParameter returnParamMap;
private NativeWebRequest webRequest; private NativeWebRequest webRequest;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
this.resolver = new ModelMethodProcessor(); processor = new ModelMethodProcessor();
mavContainer = new ModelAndViewContainer();
Method modelMethod = getClass().getDeclaredMethod("model", Model.class); Method method = getClass().getDeclaredMethod("model", Model.class);
this.modelParameter = new MethodParameter(modelMethod, 0); paramModel = new MethodParameter(method, 0);
this.modelReturnType = new MethodParameter(modelMethod, -1); returnParamModel = new MethodParameter(method, -1);
Method mapMethod = getClass().getDeclaredMethod("map", Map.class); method = getClass().getDeclaredMethod("map", Map.class);
this.mapParameter = new MethodParameter(mapMethod, 0); paramMap = new MethodParameter(method, 0);
this.mapReturnType = new MethodParameter(mapMethod, 0); returnParamMap = new MethodParameter(method, 0);
this.webRequest = new ServletWebRequest(new MockHttpServletRequest()); webRequest = new ServletWebRequest(new MockHttpServletRequest());
} }
@Test @Test
public void supportsParameter() { public void supportsParameter() {
assertTrue(resolver.supportsParameter(modelParameter)); assertTrue(processor.supportsParameter(paramModel));
assertTrue(resolver.supportsParameter(mapParameter)); assertTrue(processor.supportsParameter(paramMap));
} }
@Test @Test
public void supportsReturnType() { public void supportsReturnType() {
assertTrue(resolver.supportsReturnType(modelReturnType)); assertTrue(processor.supportsReturnType(returnParamModel));
assertTrue(resolver.supportsReturnType(mapReturnType)); assertTrue(processor.supportsReturnType(returnParamMap));
} }
@Test @Test
public void resolveArgumentValue() throws Exception { public void resolveArgumentValue() throws Exception {
ModelAndViewContainer mavContainer = new ModelAndViewContainer(); Object result = processor.resolveArgument(paramModel, mavContainer, webRequest, null);
Object result = resolver.resolveArgument(modelParameter, mavContainer, webRequest, null);
assertSame(mavContainer.getModel(), result); assertSame(mavContainer.getModel(), result);
result = resolver.resolveArgument(mapParameter, mavContainer, webRequest, null); result = processor.resolveArgument(paramMap, mavContainer, webRequest, null);
assertSame(mavContainer.getModel(), result); assertSame(mavContainer.getModel(), result);
} }
@Test @Test
public void handleReturnValue() throws Exception { public void handleModelReturnValue() throws Exception {
ExtendedModelMap implicitModel = new ExtendedModelMap(); mavContainer.addAttribute("attr1", "value1");
implicitModel.put("attr1", "value1"); ModelMap returnValue = new ModelMap("attr2", "value2");
ExtendedModelMap returnValue = new ExtendedModelMap(); processor.handleReturnValue(returnValue , returnParamModel, mavContainer, webRequest);
returnValue.put("attr2", "value2");
ModelAndViewContainer mavContainer = new ModelAndViewContainer(implicitModel); assertEquals("value1", mavContainer.getModel().get("attr1"));
resolver.handleReturnValue(returnValue , modelReturnType, mavContainer, webRequest); assertEquals("value2", mavContainer.getModel().get("attr2"));
ModelMap actualModel = mavContainer.getModel(); }
assertEquals("value1", actualModel.get("attr1"));
assertEquals("value2", actualModel.get("attr2"));
mavContainer = new ModelAndViewContainer(implicitModel); @Test
resolver.handleReturnValue(returnValue , mapReturnType, mavContainer, webRequest); public void handleMapReturnValue() throws Exception {
actualModel = mavContainer.getModel(); mavContainer.addAttribute("attr1", "value1");
assertEquals("value1", actualModel.get("attr1")); Map<String, Object> returnValue = new ModelMap("attr2", "value2");
assertEquals("value2", actualModel.get("attr2"));
processor.handleReturnValue(returnValue , returnParamMap, mavContainer, webRequest);
assertEquals("value1", mavContainer.getModel().get("attr1"));
assertEquals("value2", mavContainer.getModel().get("attr2"));
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ -121,4 +122,5 @@ public class ModelMethodProcessorTests {
private Map<String, Object> map(Map<String, Object> map) { private Map<String, Object> map(Map<String, Object> map) {
return null; return null;
} }
} }

View File

@ -37,89 +37,97 @@ import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.context.request.ServletWebRequest;
/** /**
* Text fixture with {@link RequestHeaderMapMethodArgumentResolver}.
*
* @author Arjen Poutsma * @author Arjen Poutsma
* @author Rossen Stoyanchev
*/ */
public class RequestHeaderMapMethodArgumentResolverTests { public class RequestHeaderMapMethodArgumentResolverTests {
private RequestHeaderMapMethodArgumentResolver resolver; private RequestHeaderMapMethodArgumentResolver resolver;
private MethodParameter mapParameter; private MethodParameter paramMap;
private MethodParameter multiValueMapParameter; private MethodParameter paramMultiValueMap;
private MethodParameter httpHeadersParameter; private MethodParameter paramHttpHeaders;
private MockHttpServletRequest servletRequest; private MethodParameter paramUnsupported;
private MethodParameter unsupportedParameter;
private NativeWebRequest webRequest; private NativeWebRequest webRequest;
private MockHttpServletRequest request;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
resolver = new RequestHeaderMapMethodArgumentResolver(); resolver = new RequestHeaderMapMethodArgumentResolver();
Method method = getClass()
.getMethod("params", Map.class, MultiValueMap.class, HttpHeaders.class, Map.class);
mapParameter = new MethodParameter(method, 0);
multiValueMapParameter = new MethodParameter(method, 1);
httpHeadersParameter = new MethodParameter(method, 2);
unsupportedParameter = new MethodParameter(method, 3);
servletRequest = new MockHttpServletRequest(); Method method = getClass().getMethod("params", Map.class, MultiValueMap.class, HttpHeaders.class, Map.class);
MockHttpServletResponse servletResponse = new MockHttpServletResponse(); paramMap = new MethodParameter(method, 0);
webRequest = new ServletWebRequest(servletRequest, servletResponse); paramMultiValueMap = new MethodParameter(method, 1);
paramHttpHeaders = new MethodParameter(method, 2);
paramUnsupported = new MethodParameter(method, 3);
request = new MockHttpServletRequest();
webRequest = new ServletWebRequest(request, new MockHttpServletResponse());
} }
@Test @Test
public void supportsParameter() { public void supportsParameter() {
assertTrue("Map parameter not supported", resolver.supportsParameter(mapParameter)); assertTrue("Map parameter not supported", resolver.supportsParameter(paramMap));
assertTrue("MultiValueMap parameter not supported", resolver.supportsParameter(multiValueMapParameter)); assertTrue("MultiValueMap parameter not supported", resolver.supportsParameter(paramMultiValueMap));
assertTrue("HttpHeaders parameter not supported", resolver.supportsParameter(httpHeadersParameter)); assertTrue("HttpHeaders parameter not supported", resolver.supportsParameter(paramHttpHeaders));
assertFalse("non-@RequestParam map supported", resolver.supportsParameter(unsupportedParameter)); assertFalse("non-@RequestParam map supported", resolver.supportsParameter(paramUnsupported));
} }
@Test @Test
@SuppressWarnings("unchecked")
public void resolveMapArgument() throws Exception { public void resolveMapArgument() throws Exception {
String headerName = "foo"; String name = "foo";
String headerValue = "bar"; String value = "bar";
Map<String, String> expected = Collections.singletonMap(headerName, headerValue); Map<String, String> expected = Collections.singletonMap(name, value);
servletRequest.addHeader(headerName, headerValue); request.addHeader(name, value);
Map<String, String> result = (Map<String, String>) resolver.resolveArgument(mapParameter, null, webRequest, null); Object result = resolver.resolveArgument(paramMap, null, webRequest, null);
assertTrue(result instanceof Map);
assertEquals("Invalid result", expected, result); assertEquals("Invalid result", expected, result);
} }
@Test @Test
@SuppressWarnings("unchecked")
public void resolveMultiValueMapArgument() throws Exception { public void resolveMultiValueMapArgument() throws Exception {
String headerName = "foo"; String name = "foo";
String headerValue1 = "bar"; String value1 = "bar";
String headerValue2 = "baz"; String value2 = "baz";
MultiValueMap<String, String> expected = new LinkedMultiValueMap<String, String>(1);
expected.add(headerName, headerValue1);
expected.add(headerName, headerValue2);
servletRequest.addHeader(headerName, headerValue1);
servletRequest.addHeader(headerName, headerValue2);
MultiValueMap<String, String> result = request.addHeader(name, value1);
(MultiValueMap<String, String>) resolver.resolveArgument(multiValueMapParameter, null, webRequest, null); request.addHeader(name, value2);
MultiValueMap<String, String> expected = new LinkedMultiValueMap<String, String>(1);
expected.add(name, value1);
expected.add(name, value2);
Object result = resolver.resolveArgument(paramMultiValueMap, null, webRequest, null);
assertTrue(result instanceof MultiValueMap);
assertEquals("Invalid result", expected, result); assertEquals("Invalid result", expected, result);
} }
@Test @Test
public void resolveHttpHeadersArgument() throws Exception { public void resolveHttpHeadersArgument() throws Exception {
String headerName = "foo"; String name = "foo";
String headerValue1 = "bar"; String value1 = "bar";
String headerValue2 = "baz"; String value2 = "baz";
HttpHeaders expected = new HttpHeaders();
expected.add(headerName, headerValue1);
expected.add(headerName, headerValue2);
servletRequest.addHeader(headerName, headerValue1);
servletRequest.addHeader(headerName, headerValue2);
HttpHeaders result = (HttpHeaders) resolver.resolveArgument(httpHeadersParameter, null, webRequest, null); request.addHeader(name, value1);
request.addHeader(name, value2);
HttpHeaders expected = new HttpHeaders();
expected.add(name, value1);
expected.add(name, value2);
Object result = resolver.resolveArgument(paramHttpHeaders, null, webRequest, null);
assertTrue(result instanceof HttpHeaders);
assertEquals("Invalid result", expected, result); assertEquals("Invalid result", expected, result);
} }
@ -127,8 +135,6 @@ public class RequestHeaderMapMethodArgumentResolverTests {
@RequestHeader MultiValueMap<?, ?> param2, @RequestHeader MultiValueMap<?, ?> param2,
@RequestHeader HttpHeaders param3, @RequestHeader HttpHeaders param3,
Map<?,?> unsupported) { Map<?,?> unsupported) {
} }
} }

View File

@ -37,6 +37,8 @@ import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.support.GenericWebApplicationContext; import org.springframework.web.context.support.GenericWebApplicationContext;
/** /**
* Test fixture with {@link RequestHeaderMethodArgumentResolver}.
*
* @author Arjen Poutsma * @author Arjen Poutsma
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
@ -44,15 +46,11 @@ public class RequestHeaderMethodArgumentResolverTests {
private RequestHeaderMethodArgumentResolver resolver; private RequestHeaderMethodArgumentResolver resolver;
private MethodParameter stringParameter; private MethodParameter paramNamedDefaultValueStringHeader;
private MethodParameter paramNamedValueStringArray;
private MethodParameter stringArrayParameter; private MethodParameter paramSystemProperty;
private MethodParameter paramContextPath;
private MethodParameter systemPropertyParameter; private MethodParameter paramNamedValueMap;
private MethodParameter contextPathParameter;
private MethodParameter otherParameter;
private MockHttpServletRequest servletRequest; private MockHttpServletRequest servletRequest;
@ -62,15 +60,14 @@ public class RequestHeaderMethodArgumentResolverTests {
public void setUp() throws Exception { public void setUp() throws Exception {
GenericWebApplicationContext context = new GenericWebApplicationContext(); GenericWebApplicationContext context = new GenericWebApplicationContext();
context.refresh(); context.refresh();
resolver = new RequestHeaderMethodArgumentResolver(context.getBeanFactory()); resolver = new RequestHeaderMethodArgumentResolver(context.getBeanFactory());
Method method = getClass().getMethod("params", String.class, String[].class, String.class, String.class, Map.class); Method method = getClass().getMethod("params", String.class, String[].class, String.class, String.class, Map.class);
stringParameter = new MethodParameter(method, 0); paramNamedDefaultValueStringHeader = new MethodParameter(method, 0);
stringArrayParameter = new MethodParameter(method, 1); paramNamedValueStringArray = new MethodParameter(method, 1);
systemPropertyParameter = new MethodParameter(method, 2); paramSystemProperty = new MethodParameter(method, 2);
contextPathParameter = new MethodParameter(method, 3); paramContextPath = new MethodParameter(method, 3);
otherParameter = new MethodParameter(method, 4); paramNamedValueMap = new MethodParameter(method, 4);
servletRequest = new MockHttpServletRequest(); servletRequest = new MockHttpServletRequest();
webRequest = new ServletWebRequest(servletRequest, new MockHttpServletResponse()); webRequest = new ServletWebRequest(servletRequest, new MockHttpServletResponse());
@ -86,9 +83,9 @@ public class RequestHeaderMethodArgumentResolverTests {
@Test @Test
public void supportsParameter() { public void supportsParameter() {
assertTrue("String parameter not supported", resolver.supportsParameter(stringParameter)); assertTrue("String parameter not supported", resolver.supportsParameter(paramNamedDefaultValueStringHeader));
assertTrue("String array parameter not supported", resolver.supportsParameter(stringArrayParameter)); assertTrue("String array parameter not supported", resolver.supportsParameter(paramNamedValueStringArray));
assertFalse("non-@RequestParam parameter supported", resolver.supportsParameter(otherParameter)); assertFalse("non-@RequestParam parameter supported", resolver.supportsParameter(paramNamedValueMap));
} }
@Test @Test
@ -96,7 +93,9 @@ public class RequestHeaderMethodArgumentResolverTests {
String expected = "foo"; String expected = "foo";
servletRequest.addHeader("name", expected); servletRequest.addHeader("name", expected);
String result = (String) resolver.resolveArgument(stringParameter, null, webRequest, null); Object result = resolver.resolveArgument(paramNamedDefaultValueStringHeader, null, webRequest, null);
assertTrue(result instanceof String);
assertEquals("Invalid result", expected, result); assertEquals("Invalid result", expected, result);
} }
@ -105,39 +104,50 @@ public class RequestHeaderMethodArgumentResolverTests {
String[] expected = new String[]{"foo", "bar"}; String[] expected = new String[]{"foo", "bar"};
servletRequest.addHeader("name", expected); servletRequest.addHeader("name", expected);
String[] result = (String[]) resolver.resolveArgument(stringArrayParameter, null, webRequest, null); Object result = resolver.resolveArgument(paramNamedValueStringArray, null, webRequest, null);
assertArrayEquals("Invalid result", expected, result);
assertTrue(result instanceof String[]);
assertArrayEquals("Invalid result", expected, (String[]) result);
} }
@Test @Test
public void resolveDefaultValue() throws Exception { public void resolveDefaultValue() throws Exception {
String result = (String) resolver.resolveArgument(stringParameter, null, webRequest, null); Object result = resolver.resolveArgument(paramNamedDefaultValueStringHeader, null, webRequest, null);
assertTrue(result instanceof String);
assertEquals("Invalid result", "bar", result); assertEquals("Invalid result", "bar", result);
} }
@Test @Test
public void resolveDefaultValueFromSystemProperty() throws Exception { public void resolveDefaultValueFromSystemProperty() throws Exception {
System.setProperty("header", "bar"); System.setProperty("systemProperty", "bar");
String result = (String) resolver.resolveArgument(systemPropertyParameter, null, webRequest, null); Object result = resolver.resolveArgument(paramSystemProperty, null, webRequest, null);
System.clearProperty("systemProperty");
assertTrue(result instanceof String);
assertEquals("bar", result); assertEquals("bar", result);
} }
@Test @Test
public void resolveDefaultValueFromRequest() throws Exception { public void resolveDefaultValueFromRequest() throws Exception {
servletRequest.setContextPath("/bar"); servletRequest.setContextPath("/bar");
String result = (String) resolver.resolveArgument(contextPathParameter, null, webRequest, null); Object result = resolver.resolveArgument(paramContextPath, null, webRequest, null);
assertTrue(result instanceof String);
assertEquals("/bar", result); assertEquals("/bar", result);
} }
@Test(expected = IllegalStateException.class) @Test(expected = IllegalStateException.class)
public void notFound() throws Exception { public void notFound() throws Exception {
String result = (String) resolver.resolveArgument(stringArrayParameter, null, webRequest, null); Object result = resolver.resolveArgument(paramNamedValueStringArray, null, webRequest, null);
assertTrue(result instanceof String);
assertEquals("Invalid result", "bar", result); assertEquals("Invalid result", "bar", result);
} }
public void params(@RequestHeader(value = "name", defaultValue = "bar") String param1, public void params(@RequestHeader(value = "name", defaultValue = "bar") String param1,
@RequestHeader("name") String[] param2, @RequestHeader("name") String[] param2,
@RequestHeader(value = "name", defaultValue="#{systemProperties.header}") String param3, @RequestHeader(value = "name", defaultValue="#{systemProperties.systemProperty}") String param3,
@RequestHeader(value = "name", defaultValue="#{request.contextPath}") String param4, @RequestHeader(value = "name", defaultValue="#{request.contextPath}") String param4,
@RequestHeader("name") Map<?, ?> unsupported) { @RequestHeader("name") Map<?, ?> unsupported) {
} }

View File

@ -36,77 +36,83 @@ import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.context.request.ServletWebRequest;
/** /**
* Test fixture with {@link RequestParamMapMethodArgumentResolver}.
*
* @author Arjen Poutsma * @author Arjen Poutsma
* @author Rossen Stoyanchev
*/ */
public class RequestParamMapMethodArgumentResolverTests { public class RequestParamMapMethodArgumentResolverTests {
private RequestParamMapMethodArgumentResolver resolver; private RequestParamMapMethodArgumentResolver resolver;
private MethodParameter mapParameter; private MethodParameter paramMap;
private MethodParameter multiValueMapParameter; private MethodParameter paramMultiValueMap;
private MockHttpServletRequest servletRequest; private MethodParameter paramNamedMap;
private MethodParameter paramMapWithoutAnnot;
private NativeWebRequest webRequest; private NativeWebRequest webRequest;
private MethodParameter unsupportedParameter; private MockHttpServletRequest request;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
resolver = new RequestParamMapMethodArgumentResolver(); resolver = new RequestParamMapMethodArgumentResolver();
Method method = getClass()
.getMethod("params", Map.class, MultiValueMap.class, Map.class);
mapParameter = new MethodParameter(method, 0);
multiValueMapParameter = new MethodParameter(method, 1);
unsupportedParameter = new MethodParameter(method, 2);
servletRequest = new MockHttpServletRequest(); Method method = getClass().getMethod("params", Map.class, MultiValueMap.class, Map.class, Map.class);
MockHttpServletResponse servletResponse = new MockHttpServletResponse(); paramMap = new MethodParameter(method, 0);
webRequest = new ServletWebRequest(servletRequest, servletResponse); paramMultiValueMap = new MethodParameter(method, 1);
paramNamedMap = new MethodParameter(method, 2);
paramMapWithoutAnnot = new MethodParameter(method, 3);
request = new MockHttpServletRequest();
webRequest = new ServletWebRequest(request, new MockHttpServletResponse());
} }
@Test @Test
public void supportsParameter() { public void supportsParameter() {
assertTrue("Map parameter not supported", resolver.supportsParameter(mapParameter)); assertTrue("Map parameter not supported", resolver.supportsParameter(paramMap));
assertTrue("MultiValueMap parameter not supported", resolver.supportsParameter(multiValueMapParameter)); assertTrue("MultiValueMap parameter not supported", resolver.supportsParameter(paramMultiValueMap));
assertFalse("non-@RequestParam map supported", resolver.supportsParameter(unsupportedParameter)); assertFalse("Map with name supported", resolver.supportsParameter(paramNamedMap));
assertFalse("non-@RequestParam map supported", resolver.supportsParameter(paramMapWithoutAnnot));
} }
@Test @Test
@SuppressWarnings("unchecked")
public void resolveMapArgument() throws Exception { public void resolveMapArgument() throws Exception {
String headerName = "foo"; String name = "foo";
String headerValue = "bar"; String value = "bar";
Map<String, String> expected = Collections.singletonMap(headerName, headerValue); request.addParameter(name, value);
servletRequest.addParameter(headerName, headerValue); Map<String, String> expected = Collections.singletonMap(name, value);
Map<String, String> result = (Map<String, String>) resolver.resolveArgument(mapParameter, null, webRequest, null); Object result = resolver.resolveArgument(paramMap, null, webRequest, null);
assertTrue(result instanceof Map);
assertEquals("Invalid result", expected, result); assertEquals("Invalid result", expected, result);
} }
@Test @Test
@SuppressWarnings("unchecked")
public void resolveMultiValueMapArgument() throws Exception { public void resolveMultiValueMapArgument() throws Exception {
String headerName = "foo"; String name = "foo";
String headerValue1 = "bar"; String value1 = "bar";
String headerValue2 = "baz"; String value2 = "baz";
MultiValueMap<String, String> expected = new LinkedMultiValueMap<String, String>(1); request.addParameter(name, new String[]{value1, value2});
expected.add(headerName, headerValue1);
expected.add(headerName, headerValue2);
servletRequest.addParameter(headerName, new String[]{headerValue1, headerValue2});
MultiValueMap<String, String> result = MultiValueMap<String, String> expected = new LinkedMultiValueMap<String, String>(1);
(MultiValueMap<String, String>) resolver.resolveArgument(multiValueMapParameter, null, webRequest, null); expected.add(name, value1);
expected.add(name, value2);
Object result = resolver.resolveArgument(paramMultiValueMap, null, webRequest, null);
assertTrue(result instanceof MultiValueMap);
assertEquals("Invalid result", expected, result); assertEquals("Invalid result", expected, result);
} }
public void params(@RequestParam Map<?, ?> param1, public void params(@RequestParam Map<?, ?> param1,
@RequestParam MultiValueMap<?, ?> param2, @RequestParam MultiValueMap<?, ?> param2,
Map<?, ?> unsupported) { @RequestParam("name") Map<?, ?> param3,
Map<?, ?> param4) {
} }
} }

View File

@ -39,115 +39,125 @@ import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
/** /**
* Test fixture with {@link RequestParamMethodArgumentResolver}.
*
* @author Arjen Poutsma * @author Arjen Poutsma
* @author Rossen Stoyanchev
*/ */
public class RequestParamMethodArgumentResolverTests { public class RequestParamMethodArgumentResolverTests {
private RequestParamMethodArgumentResolver resolver; private RequestParamMethodArgumentResolver resolver;
private MethodParameter stringParameter; private MethodParameter paramNamedDefaultValueString;
private MethodParameter paramNamedStringArray;
private MethodParameter stringArrayParameter; private MethodParameter paramNamedMap;
private MethodParameter paramMultiPartFile;
private MethodParameter mapParameter; private MethodParameter paramMap;
private MethodParameter paramStringNotAnnot;
private MethodParameter fileParameter;
private MethodParameter otherParameter;
private MockHttpServletRequest servletRequest;
private NativeWebRequest webRequest; private NativeWebRequest webRequest;
private MethodParameter plainParameter; private MockHttpServletRequest request;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
resolver = new RequestParamMethodArgumentResolver(null, true); resolver = new RequestParamMethodArgumentResolver(null, true);
Method method = getClass()
.getMethod("params", String.class, String[].class, Map.class, MultipartFile.class, Map.class, String.class);
stringParameter = new MethodParameter(method, 0);
stringArrayParameter = new MethodParameter(method, 1);
mapParameter = new MethodParameter(method, 2);
fileParameter = new MethodParameter(method, 3);
otherParameter = new MethodParameter(method, 4);
plainParameter = new MethodParameter(method, 5);
plainParameter.initParameterNameDiscovery(new LocalVariableTableParameterNameDiscoverer()); Method method = getClass().getMethod("params",
String.class, String[].class, Map.class, MultipartFile.class, Map.class, String.class);
servletRequest = new MockHttpServletRequest(); paramNamedDefaultValueString = new MethodParameter(method, 0);
MockHttpServletResponse servletResponse = new MockHttpServletResponse(); paramNamedStringArray = new MethodParameter(method, 1);
webRequest = new ServletWebRequest(servletRequest, servletResponse); paramNamedMap = new MethodParameter(method, 2);
paramMultiPartFile = new MethodParameter(method, 3);
paramMap = new MethodParameter(method, 4);
paramStringNotAnnot = new MethodParameter(method, 5);
paramStringNotAnnot.initParameterNameDiscovery(new LocalVariableTableParameterNameDiscoverer());
request = new MockHttpServletRequest();
webRequest = new ServletWebRequest(request, new MockHttpServletResponse());
} }
@Test @Test
public void supportsParameter() { public void supportsParameter() {
assertTrue("String parameter not supported", resolver.supportsParameter(stringParameter)); resolver = new RequestParamMethodArgumentResolver(null, true);
assertTrue("String array parameter not supported", resolver.supportsParameter(stringArrayParameter)); assertTrue("String parameter not supported", resolver.supportsParameter(paramNamedDefaultValueString));
assertTrue("Named map not parameter supported", resolver.supportsParameter(mapParameter)); assertTrue("String array parameter not supported", resolver.supportsParameter(paramNamedStringArray));
assertTrue("MultipartFile parameter not supported", resolver.supportsParameter(fileParameter)); assertTrue("Named map not parameter supported", resolver.supportsParameter(paramNamedMap));
assertFalse("non-@RequestParam parameter supported", resolver.supportsParameter(otherParameter)); assertTrue("MultipartFile parameter not supported", resolver.supportsParameter(paramMultiPartFile));
assertTrue("Simple type params supported w/o annotations", resolver.supportsParameter(plainParameter)); assertFalse("non-@RequestParam parameter supported", resolver.supportsParameter(paramMap));
assertTrue("Simple type params supported w/o annotations", resolver.supportsParameter(paramStringNotAnnot));
resolver = new RequestParamMethodArgumentResolver(null, false); resolver = new RequestParamMethodArgumentResolver(null, false);
assertFalse(resolver.supportsParameter(plainParameter)); assertFalse(resolver.supportsParameter(paramStringNotAnnot));
} }
@Test @Test
public void resolveStringArgument() throws Exception { public void resolveStringArgument() throws Exception {
String expected = "foo"; String expected = "foo";
servletRequest.addParameter("name", expected); request.addParameter("name", expected);
String result = (String) resolver.resolveArgument(stringParameter, null, webRequest, null); Object result = resolver.resolveArgument(paramNamedDefaultValueString, null, webRequest, null);
assertTrue(result instanceof String);
assertEquals("Invalid result", expected, result); assertEquals("Invalid result", expected, result);
} }
@Test @Test
public void resolveStringArrayArgument() throws Exception { public void resolveStringArrayArgument() throws Exception {
String[] expected = new String[]{"foo", "bar"}; String[] expected = new String[]{"foo", "bar"};
servletRequest.addParameter("name", expected); request.addParameter("name", expected);
String[] result = (String[]) resolver.resolveArgument(stringArrayParameter, null, webRequest, null); Object result = resolver.resolveArgument(paramNamedStringArray, null, webRequest, null);
assertArrayEquals("Invalid result", expected, result);
assertTrue(result instanceof String[]);
assertArrayEquals("Invalid result", expected, (String[]) result);
} }
@Test @Test
public void resolveMultipartFileArgument() throws Exception { public void resolveMultipartFileArgument() throws Exception {
MockMultipartHttpServletRequest servletRequest = new MockMultipartHttpServletRequest(); MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest();
MultipartFile expected = new MockMultipartFile("file", "Hello World".getBytes()); MultipartFile expected = new MockMultipartFile("file", "Hello World".getBytes());
servletRequest.addFile(expected); request.addFile(expected);
webRequest = new ServletWebRequest(servletRequest); webRequest = new ServletWebRequest(request);
MultipartFile result = (MultipartFile) resolver.resolveArgument(fileParameter, null, webRequest, null); Object result = resolver.resolveArgument(paramMultiPartFile, null, webRequest, null);
assertTrue(result instanceof MultipartFile);
assertEquals("Invalid result", expected, result); assertEquals("Invalid result", expected, result);
} }
@Test @Test
public void resolveDefaultValue() throws Exception { public void resolveDefaultValue() throws Exception {
String result = (String) resolver.resolveArgument(stringParameter, null, webRequest, null); Object result = resolver.resolveArgument(paramNamedDefaultValueString, null, webRequest, null);
assertTrue(result instanceof String);
assertEquals("Invalid result", "bar", result); assertEquals("Invalid result", "bar", result);
} }
@Test(expected = MissingServletRequestParameterException.class) @Test(expected = MissingServletRequestParameterException.class)
public void notFound() throws Exception { public void notFound() throws Exception {
String result = (String) resolver.resolveArgument(stringArrayParameter, null, webRequest, null); Object result = resolver.resolveArgument(paramNamedStringArray, null, webRequest, null);
assertTrue(result instanceof String);
assertEquals("Invalid result", "bar", result); assertEquals("Invalid result", "bar", result);
} }
@Test @Test
public void resolveSimpleTypeParam() throws Exception { public void resolveSimpleTypeParam() throws Exception {
servletRequest.setParameter("plainParam", "plainValue"); request.setParameter("paramStringNotAnnot", "plainValue");
String result = (String) resolver.resolveArgument(plainParameter, null, webRequest, null); Object result = resolver.resolveArgument(paramStringNotAnnot, null, webRequest, null);
assertTrue(result instanceof String);
assertEquals("plainValue", result); assertEquals("plainValue", result);
} }
public void params(@RequestParam(value = "name", defaultValue = "bar") String param1, public void params(@RequestParam(value = "name", defaultValue = "bar") String param1,
@RequestParam("name") String[] param2, @RequestParam("name") String[] param2,
@RequestParam("name") Map<?, ?> param3, @RequestParam("name") Map<?, ?> param3,
@RequestParam(value = "file") MultipartFile file, @RequestParam(value = "file") MultipartFile param4,
@RequestParam Map<?, ?> unsupported, @RequestParam Map<?, ?> param5,
String plainParam) { String paramStringNotAnnot) {
} }
} }

View File

@ -35,14 +35,17 @@ import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.context.request.ServletWebRequest;
/** /**
* Test fixture with {@link WebArgumentResolverAdapterTests}.
*
* @author Arjen Poutsma * @author Arjen Poutsma
* @author Rossen Stoyanchev
*/ */
public class WebArgumentResolverAdapterTests { public class WebArgumentResolverAdapterTests {
private WebArgumentResolver adaptee;
private TestWebArgumentResolverAdapter adapter; private TestWebArgumentResolverAdapter adapter;
private WebArgumentResolver adaptee;
private MethodParameter parameter; private MethodParameter parameter;
private NativeWebRequest webRequest; private NativeWebRequest webRequest;
@ -51,10 +54,10 @@ public class WebArgumentResolverAdapterTests {
public void setUp() throws Exception { public void setUp() throws Exception {
adaptee = createMock(WebArgumentResolver.class); adaptee = createMock(WebArgumentResolver.class);
adapter = new TestWebArgumentResolverAdapter(adaptee); adapter = new TestWebArgumentResolverAdapter(adaptee);
parameter = new MethodParameter(getClass().getMethod("handle", Integer.TYPE), 0); parameter = new MethodParameter(getClass().getMethod("handle", Integer.TYPE), 0);
webRequest = new ServletWebRequest(new MockHttpServletRequest()); webRequest = new ServletWebRequest(new MockHttpServletRequest());
// Expose request to the current thread (for SpEL expressions)
RequestContextHolder.setRequestAttributes(webRequest); RequestContextHolder.setRequestAttributes(webRequest);
} }
@ -66,11 +69,9 @@ public class WebArgumentResolverAdapterTests {
@Test @Test
public void supportsParameter() throws Exception { public void supportsParameter() throws Exception {
expect(adaptee.resolveArgument(parameter, webRequest)).andReturn(42); expect(adaptee.resolveArgument(parameter, webRequest)).andReturn(42);
replay(adaptee); replay(adaptee);
boolean result = adapter.supportsParameter(parameter); assertTrue("Parameter not supported", adapter.supportsParameter(parameter));
assertTrue("Parameter not supported", result);
verify(adaptee); verify(adaptee);
} }
@ -78,11 +79,9 @@ public class WebArgumentResolverAdapterTests {
@Test @Test
public void supportsParameterUnresolved() throws Exception { public void supportsParameterUnresolved() throws Exception {
expect(adaptee.resolveArgument(parameter, webRequest)).andReturn(WebArgumentResolver.UNRESOLVED); expect(adaptee.resolveArgument(parameter, webRequest)).andReturn(WebArgumentResolver.UNRESOLVED);
replay(adaptee); replay(adaptee);
boolean result = adapter.supportsParameter(parameter); assertFalse("Parameter supported", adapter.supportsParameter(parameter));
assertFalse("Parameter supported", result);
verify(adaptee); verify(adaptee);
} }
@ -90,11 +89,9 @@ public class WebArgumentResolverAdapterTests {
@Test @Test
public void supportsParameterWrongType() throws Exception { public void supportsParameterWrongType() throws Exception {
expect(adaptee.resolveArgument(parameter, webRequest)).andReturn("Foo"); expect(adaptee.resolveArgument(parameter, webRequest)).andReturn("Foo");
replay(adaptee); replay(adaptee);
boolean result = adapter.supportsParameter(parameter); assertFalse("Parameter supported", adapter.supportsParameter(parameter));
assertFalse("Parameter supported", result);
verify(adaptee); verify(adaptee);
} }
@ -102,11 +99,9 @@ public class WebArgumentResolverAdapterTests {
@Test @Test
public void supportsParameterThrowsException() throws Exception { public void supportsParameterThrowsException() throws Exception {
expect(adaptee.resolveArgument(parameter, webRequest)).andThrow(new Exception()); expect(adaptee.resolveArgument(parameter, webRequest)).andThrow(new Exception());
replay(adaptee); replay(adaptee);
boolean result = adapter.supportsParameter(parameter); assertFalse("Parameter supported", adapter.supportsParameter(parameter));
assertFalse("Parameter supported", result);
verify(adaptee); verify(adaptee);
} }
@ -115,7 +110,6 @@ public class WebArgumentResolverAdapterTests {
public void resolveArgument() throws Exception { public void resolveArgument() throws Exception {
int expected = 42; int expected = 42;
expect(adaptee.resolveArgument(parameter, webRequest)).andReturn(expected); expect(adaptee.resolveArgument(parameter, webRequest)).andReturn(expected);
replay(adaptee); replay(adaptee);
Object result = adapter.resolveArgument(parameter, null, webRequest, null); Object result = adapter.resolveArgument(parameter, null, webRequest, null);
@ -128,7 +122,6 @@ public class WebArgumentResolverAdapterTests {
@Test(expected = IllegalStateException.class) @Test(expected = IllegalStateException.class)
public void resolveArgumentUnresolved() throws Exception { public void resolveArgumentUnresolved() throws Exception {
expect(adaptee.resolveArgument(parameter, webRequest)).andReturn(WebArgumentResolver.UNRESOLVED); expect(adaptee.resolveArgument(parameter, webRequest)).andReturn(WebArgumentResolver.UNRESOLVED);
replay(adaptee); replay(adaptee);
adapter.resolveArgument(parameter, null, webRequest, null); adapter.resolveArgument(parameter, null, webRequest, null);
@ -139,7 +132,6 @@ public class WebArgumentResolverAdapterTests {
@Test(expected = IllegalStateException.class) @Test(expected = IllegalStateException.class)
public void resolveArgumentWrongType() throws Exception { public void resolveArgumentWrongType() throws Exception {
expect(adaptee.resolveArgument(parameter, webRequest)).andReturn("Foo"); expect(adaptee.resolveArgument(parameter, webRequest)).andReturn("Foo");
replay(adaptee); replay(adaptee);
adapter.resolveArgument(parameter, null, webRequest, null); adapter.resolveArgument(parameter, null, webRequest, null);
@ -150,7 +142,6 @@ public class WebArgumentResolverAdapterTests {
@Test(expected = Exception.class) @Test(expected = Exception.class)
public void resolveArgumentThrowsException() throws Exception { public void resolveArgumentThrowsException() throws Exception {
expect(adaptee.resolveArgument(parameter, webRequest)).andThrow(new Exception()); expect(adaptee.resolveArgument(parameter, webRequest)).andThrow(new Exception());
replay(adaptee); replay(adaptee);
adapter.resolveArgument(parameter, null, webRequest, null); adapter.resolveArgument(parameter, null, webRequest, null);
@ -159,7 +150,6 @@ public class WebArgumentResolverAdapterTests {
} }
public void handle(int param) { public void handle(int param) {
} }
private class TestWebArgumentResolverAdapter extends AbstractWebArgumentResolverAdapter { private class TestWebArgumentResolverAdapter extends AbstractWebArgumentResolverAdapter {

View File

@ -27,60 +27,60 @@ import org.junit.Test;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
/** /**
* Test fixture for {@link HandlerMethodArgumentResolverComposite} unit tests. * Test fixture with {@link HandlerMethodArgumentResolverComposite}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
public class HandlerMethodArgumentResolverCompositeTests { public class HandlerMethodArgumentResolverCompositeTests {
private HandlerMethodArgumentResolverComposite composite; private HandlerMethodArgumentResolverComposite resolvers;
private MethodParameter paramInteger; private MethodParameter paramInt;
private MethodParameter paramString; private MethodParameter paramStr;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
this.composite = new HandlerMethodArgumentResolverComposite(); resolvers = new HandlerMethodArgumentResolverComposite();
Method method = getClass().getDeclaredMethod("handle", Integer.class, String.class); Method method = getClass().getDeclaredMethod("handle", Integer.class, String.class);
this.paramInteger = new MethodParameter(method, 0); paramInt = new MethodParameter(method, 0);
this.paramString = new MethodParameter(method, 1); paramStr = new MethodParameter(method, 1);
} }
@Test @Test
public void supportsParameter() throws Exception { public void supportsParameter() throws Exception {
registerResolver(Integer.class, null, false); registerResolver(Integer.class, null);
assertTrue(this.composite.supportsParameter(paramInteger)); assertTrue(this.resolvers.supportsParameter(paramInt));
assertFalse(this.composite.supportsParameter(paramString)); assertFalse(this.resolvers.supportsParameter(paramStr));
} }
@Test @Test
public void resolveArgument() throws Exception { public void resolveArgument() throws Exception {
registerResolver(Integer.class, Integer.valueOf(55), false); registerResolver(Integer.class, Integer.valueOf(55));
Object resolvedValue = this.composite.resolveArgument(paramInteger, null, null, null); Object resolvedValue = this.resolvers.resolveArgument(paramInt, null, null, null);
assertEquals(Integer.valueOf(55), resolvedValue); assertEquals(Integer.valueOf(55), resolvedValue);
} }
@Test @Test
public void resolveArgumentMultipleResolvers() throws Exception { public void checkArgumentResolverOrder() throws Exception {
registerResolver(Integer.class, Integer.valueOf(1), false); registerResolver(Integer.class, Integer.valueOf(1));
registerResolver(Integer.class, Integer.valueOf(2), false); registerResolver(Integer.class, Integer.valueOf(2));
Object resolvedValue = this.composite.resolveArgument(paramInteger, null, null, null); Object resolvedValue = this.resolvers.resolveArgument(paramInt, null, null, null);
assertEquals("Didn't use the first registered resolver", Integer.valueOf(1), resolvedValue); assertEquals("Didn't use the first registered resolver", Integer.valueOf(1), resolvedValue);
} }
@Test(expected=IllegalStateException.class) @Test(expected=IllegalStateException.class)
public void noSuitableArgumentResolver() throws Exception { public void noSuitableArgumentResolver() throws Exception {
this.composite.resolveArgument(paramString, null, null, null); this.resolvers.resolveArgument(paramStr, null, null, null);
} }
protected StubArgumentResolver registerResolver(Class<?> supportedType, Object stubValue, boolean usesResponse) { protected StubArgumentResolver registerResolver(Class<?> supportedType, Object stubValue) {
StubArgumentResolver resolver = new StubArgumentResolver(supportedType, stubValue, usesResponse); StubArgumentResolver resolver = new StubArgumentResolver(supportedType, stubValue);
this.composite.registerArgumentResolver(resolver); this.resolvers.addResolver(resolver);
return resolver; return resolver;
} }

View File

@ -26,65 +26,63 @@ import org.junit.Test;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
/** /**
* Test fixture for {@link HandlerMethodReturnValueHandlerComposite} unit tests. * Test fixture with {@link HandlerMethodReturnValueHandlerComposite}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
public class HandlerMethodReturnValueHandlerCompositeTests { public class HandlerMethodReturnValueHandlerCompositeTests {
private HandlerMethodReturnValueHandlerComposite composite; private HandlerMethodReturnValueHandlerComposite handlers;
ModelAndViewContainer mavContainer; ModelAndViewContainer mavContainer;
private MethodParameter paramInteger; private MethodParameter paramInt;
private MethodParameter paramString; private MethodParameter paramStr;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
this.composite = new HandlerMethodReturnValueHandlerComposite(); handlers = new HandlerMethodReturnValueHandlerComposite();
this.paramInteger = new MethodParameter(getClass().getDeclaredMethod("handleInteger"), -1);
this.paramString = new MethodParameter(getClass().getDeclaredMethod("handleString"), -1);
mavContainer = new ModelAndViewContainer(); mavContainer = new ModelAndViewContainer();
paramInt = new MethodParameter(getClass().getDeclaredMethod("handleInteger"), -1);
paramStr = new MethodParameter(getClass().getDeclaredMethod("handleString"), -1);
} }
@Test @Test
public void supportsReturnType() throws Exception { public void supportsReturnType() throws Exception {
registerReturnValueHandler(Integer.class, false); registerHandler(Integer.class);
assertTrue(this.composite.supportsReturnType(paramInteger)); assertTrue(this.handlers.supportsReturnType(paramInt));
assertFalse(this.composite.supportsReturnType(paramString)); assertFalse(this.handlers.supportsReturnType(paramStr));
} }
@Test @Test
public void handleReturnValue() throws Exception { public void handleReturnValue() throws Exception {
StubReturnValueHandler handler = registerReturnValueHandler(Integer.class, false); StubReturnValueHandler handler = registerHandler(Integer.class);
this.composite.handleReturnValue(Integer.valueOf(55), paramInteger, mavContainer, null); this.handlers.handleReturnValue(Integer.valueOf(55), paramInt, mavContainer, null);
assertEquals(Integer.valueOf(55), handler.getUnhandledReturnValue()); assertEquals(Integer.valueOf(55), handler.getReturnValue());
} }
@Test @Test
public void handleReturnValueMultipleHandlers() throws Exception { public void handleReturnValueMultipleHandlers() throws Exception {
StubReturnValueHandler handler1 = registerReturnValueHandler(Integer.class, false); StubReturnValueHandler h1 = registerHandler(Integer.class);
StubReturnValueHandler handler2 = registerReturnValueHandler(Integer.class, false); StubReturnValueHandler h2 = registerHandler(Integer.class);
this.composite.handleReturnValue(Integer.valueOf(55), paramInteger, mavContainer, null); this.handlers.handleReturnValue(Integer.valueOf(55), paramInt, mavContainer, null);
assertEquals("Didn't use the 1st registered handler", Integer.valueOf(55), handler1.getUnhandledReturnValue()); assertEquals("Didn't use the 1st registered handler", Integer.valueOf(55), h1.getReturnValue());
assertNull("Shouldn't have use the 2nd registered handler", handler2.getUnhandledReturnValue()); assertNull("Shouldn't have use the 2nd registered handler", h2.getReturnValue());
} }
@Test(expected=IllegalStateException.class) @Test(expected=IllegalStateException.class)
public void noSuitableReturnValueHandler() throws Exception { public void noSuitableReturnValueHandler() throws Exception {
registerReturnValueHandler(Integer.class, false); registerHandler(Integer.class);
this.composite.handleReturnValue("value", paramString, null, null); this.handlers.handleReturnValue("value", paramStr, null, null);
} }
protected StubReturnValueHandler registerReturnValueHandler(Class<?> returnType, boolean usesResponse) { private StubReturnValueHandler registerHandler(Class<?> returnType) {
StubReturnValueHandler handler = new StubReturnValueHandler(returnType, usesResponse); StubReturnValueHandler handler = new StubReturnValueHandler(returnType);
this.composite.registerReturnValueHandler(handler); handlers.addHandler(handler);
return handler; return handler;
} }

View File

@ -22,51 +22,44 @@ import java.lang.reflect.Method;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import org.springframework.http.HttpStatus;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.ServletWebRequest; import org.springframework.web.context.request.ServletWebRequest;
/** /**
* Test fixture for {@link InvocableHandlerMethod} unit tests. * Test fixture with {@link InvocableHandlerMethod}.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
public class InvocableHandlerMethodTests { public class InvocableHandlerMethodTests {
private HandlerMethodArgumentResolverComposite argResolvers; private HandlerMethodArgumentResolverComposite argumentResolvers;
private NativeWebRequest webRequest; private NativeWebRequest webRequest;
private MockHttpServletResponse response;
@Before @Before
public void setUp() throws Exception { public void setUp() throws Exception {
argResolvers = new HandlerMethodArgumentResolverComposite(); argumentResolvers = new HandlerMethodArgumentResolverComposite();
this.webRequest = new ServletWebRequest(new MockHttpServletRequest(), new MockHttpServletResponse());
response = new MockHttpServletResponse();
this.webRequest = new ServletWebRequest(new MockHttpServletRequest(), response);
} }
@Test @Test
public void argResolutionAndReturnValueHandling() throws Exception { public void resolveArgument() throws Exception {
StubArgumentResolver resolver0 = registerResolver(Integer.class, 99, false); StubArgumentResolver intResolver = addResolver(Integer.class, 99);
StubArgumentResolver resolver1 = registerResolver(String.class, "value", false); StubArgumentResolver strResolver = addResolver(String.class, "value");
InvocableHandlerMethod method = invocableHandlerMethod("handle", Integer.class, String.class);
InvocableHandlerMethod method = handlerMethod(new Handler(), "handle", Integer.class, String.class);
Object returnValue = method.invokeForRequest(webRequest, null); Object returnValue = method.invokeForRequest(webRequest, null);
assertEquals("Integer resolver not invoked", 1, resolver0.getResolvedParameterNames().size()); assertEquals("Integer resolver not invoked", 1, intResolver.getResolvedParameters().size());
assertEquals("String resolver not invoked", 1, resolver1.getResolvedParameterNames().size()); assertEquals("String resolver not invoked", 1, strResolver.getResolvedParameters().size());
assertEquals("Invalid return value", "99-value", returnValue); assertEquals("Invalid return value", "99-value", returnValue);
} }
@Test @Test
public void providedArgResolution() throws Exception { public void resolveProvidedArgument() throws Exception {
InvocableHandlerMethod method = handlerMethod(new Handler(), "handle", Integer.class, String.class); InvocableHandlerMethod method = invocableHandlerMethod("handle", Integer.class, String.class);
Object returnValue = method.invokeForRequest(webRequest, null, 99, "value"); Object returnValue = method.invokeForRequest(webRequest, null, 99, "value");
assertEquals("Expected raw return value with no handlers registered", String.class, returnValue.getClass()); assertEquals("Expected raw return value with no handlers registered", String.class, returnValue.getClass());
@ -74,29 +67,28 @@ public class InvocableHandlerMethodTests {
} }
@Test @Test
public void parameterNameDiscovery() throws Exception { public void discoverParameterName() throws Exception {
StubArgumentResolver resolver = registerResolver(Integer.class, 99, false); StubArgumentResolver resolver = addResolver(Integer.class, 99);
InvocableHandlerMethod method = invocableHandlerMethod("parameterNameDiscovery", Integer.class);
InvocableHandlerMethod method = handlerMethod(new Handler(), "parameterNameDiscovery", Integer.class);
method.invokeForRequest(webRequest, null); method.invokeForRequest(webRequest, null);
assertEquals("intArg", resolver.getResolvedParameterNames().get(0).getParameterName()); assertEquals("intArg", resolver.getResolvedParameters().get(0).getParameterName());
} }
private InvocableHandlerMethod handlerMethod(Object handler, String methodName, Class<?>... paramTypes) private StubArgumentResolver addResolver(Class<?> parameterType, Object stubValue) {
throws Exception { StubArgumentResolver resolver = new StubArgumentResolver(parameterType, stubValue);
Method method = handler.getClass().getDeclaredMethod(methodName, paramTypes); argumentResolvers.addResolver(resolver);
InvocableHandlerMethod handlerMethod = new InvocableHandlerMethod(handler, method);
handlerMethod.setHandlerMethodArgumentResolvers(argResolvers);
return handlerMethod;
}
private StubArgumentResolver registerResolver(Class<?> supportedType, Object stubValue, boolean usesResponse) {
StubArgumentResolver resolver = new StubArgumentResolver(supportedType, stubValue, usesResponse);
argResolvers.registerArgumentResolver(resolver);
return resolver; return resolver;
} }
private InvocableHandlerMethod invocableHandlerMethod(String methodName, Class<?>... paramTypes)
throws Exception {
Method method = Handler.class.getDeclaredMethod(methodName, paramTypes);
InvocableHandlerMethod handlerMethod = new InvocableHandlerMethod(new Handler(), method);
handlerMethod.setHandlerMethodArgumentResolvers(argumentResolvers);
return handlerMethod;
}
private static class Handler { private static class Handler {
@SuppressWarnings("unused") @SuppressWarnings("unused")
@ -108,15 +100,6 @@ public class InvocableHandlerMethodTests {
@RequestMapping @RequestMapping
public void parameterNameDiscovery(Integer intArg) { public void parameterNameDiscovery(Integer intArg) {
} }
@SuppressWarnings("unused")
@ResponseStatus(value = HttpStatus.BAD_REQUEST, reason = "400 Bad Request")
public void responseStatus() {
} }
@SuppressWarnings("unused")
public String usesResponse(int arg) {
return "";
}
}
} }

View File

@ -24,44 +24,34 @@ import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.request.NativeWebRequest;
/** /**
* Resolves a method argument from a stub value. Records all resolved parameters. * Resolves a method argument using a stub value and records resolved parameters.
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
public class StubArgumentResolver implements HandlerMethodArgumentResolver { public class StubArgumentResolver implements HandlerMethodArgumentResolver {
private final Class<?> supportedType; private final Class<?> parameterType;
private final Object stubValue; private final Object stubValue;
private final boolean usesResponse;
private List<MethodParameter> resolvedParameters = new ArrayList<MethodParameter>(); private List<MethodParameter> resolvedParameters = new ArrayList<MethodParameter>();
public StubArgumentResolver(Class<?> supportedType, Object stubValue, boolean usesResponse) { public StubArgumentResolver(Class<?> parameterType, Object stubValue) {
this.supportedType = supportedType; this.parameterType = parameterType;
this.stubValue = stubValue; this.stubValue = stubValue;
this.usesResponse = usesResponse;
} }
public List<MethodParameter> getResolvedParameterNames() { public List<MethodParameter> getResolvedParameters() {
return resolvedParameters; return resolvedParameters;
} }
public boolean usesResponseArgument(MethodParameter parameter) {
return this.usesResponse;
}
public boolean supportsParameter(MethodParameter parameter) { public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().equals(this.supportedType); return parameter.getParameterType().equals(this.parameterType);
} }
public Object resolveArgument(MethodParameter parameter, public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception {
this.resolvedParameters.add(parameter); this.resolvedParameters.add(parameter);
return this.stubValue; return this.stubValue;
} }
} }

View File

@ -16,48 +16,35 @@
package org.springframework.web.method.support; package org.springframework.web.method.support;
import org.springframework.core.Conventions;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.request.NativeWebRequest;
/** /**
* Handles a return value by adding it as a model attribute with a default name. * Supports a fixed return value type. Records the last handled return value.
* Records the raw return value (before handling).
* *
* @author Rossen Stoyanchev * @author Rossen Stoyanchev
*/ */
public class StubReturnValueHandler implements HandlerMethodReturnValueHandler { public class StubReturnValueHandler implements HandlerMethodReturnValueHandler {
private final Class<?> supportedReturnType; private final Class<?> returnType;
private final boolean usesResponse; private Object returnValue;
private Object unhandledReturnValue; public StubReturnValueHandler(Class<?> returnType) {
this.returnType = returnType;
public StubReturnValueHandler(Class<?> supportedReturnType, boolean usesResponse) {
this.supportedReturnType = supportedReturnType;
this.usesResponse = usesResponse;
} }
public Object getUnhandledReturnValue() { public Object getReturnValue() {
return this.unhandledReturnValue; return this.returnValue;
} }
public boolean supportsReturnType(MethodParameter returnType) { public boolean supportsReturnType(MethodParameter returnType) {
return returnType.getParameterType().equals(this.supportedReturnType); return returnType.getParameterType().equals(this.returnType);
} }
public void handleReturnValue(Object returnValue, public void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer,
MethodParameter returnType,
ModelAndViewContainer mavContainer,
NativeWebRequest webRequest) throws Exception { NativeWebRequest webRequest) throws Exception {
this.unhandledReturnValue = returnValue; this.returnValue = returnValue;
if (returnValue != null) {
mavContainer.addAttribute(Conventions.getVariableName(returnValue), returnValue);
}
} }
public boolean usesResponseArgument(MethodParameter parameter) {
return this.usesResponse;
}
} }