SPR-6464 Add @FlashAttributes annotation and FlashStatus method argument

This commit is contained in:
Rossen Stoyanchev
2011-07-27 21:46:36 +00:00
parent 2c504012ad
commit f4adf227be
15 changed files with 1104 additions and 540 deletions

View File

@@ -50,8 +50,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.bind.support.DefaultDataBinderFactory;
import org.springframework.web.bind.support.DefaultSessionAttributeStore;
import org.springframework.web.bind.support.FlashStatus;
import org.springframework.web.bind.support.SessionAttributeStore;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.bind.support.SimpleFlashStatus;
import org.springframework.web.bind.support.SimpleSessionStatus;
import org.springframework.web.bind.support.WebBindingInitializer;
import org.springframework.web.bind.support.WebDataBinderFactory;
@@ -59,6 +61,7 @@ import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.method.HandlerMethodSelector;
import org.springframework.web.method.annotation.FlashAttributesHandler;
import org.springframework.web.method.annotation.ModelFactory;
import org.springframework.web.method.annotation.SessionAttributesHandler;
import org.springframework.web.method.annotation.support.ErrorsMethodArgumentResolver;
@@ -146,6 +149,9 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
private final Map<Class<?>, SessionAttributesHandler> sessionAttributesHandlerCache =
new ConcurrentHashMap<Class<?>, SessionAttributesHandler>();
private final Map<Class<?>, FlashAttributesHandler> flashAttributesHandlerCache =
new ConcurrentHashMap<Class<?>, FlashAttributesHandler>();
private HandlerMethodArgumentResolverComposite argumentResolvers;
private HandlerMethodArgumentResolverComposite initBinderArgumentResolvers;
@@ -481,19 +487,27 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
}
/**
* Whether the given handler type defines any handler-specific session attributes via {@link SessionAttributes}.
* Also initializes the sessionAttributesHandlerCache for the given handler type.
* Whether the given handler type defines any handler-specific session attributes
* via {@link SessionAttributes}.
*/
private boolean hasSessionAttributes(Class<?> handlerType) {
SessionAttributesHandler handler = null;
SessionAttributesHandler sessionAttrsHandler = null;
synchronized(this.sessionAttributesHandlerCache) {
handler = this.sessionAttributesHandlerCache.get(handlerType);
if (handler == null) {
handler = new SessionAttributesHandler(handlerType, sessionAttributeStore);
this.sessionAttributesHandlerCache.put(handlerType, handler);
sessionAttrsHandler = this.sessionAttributesHandlerCache.get(handlerType);
if (sessionAttrsHandler == null) {
sessionAttrsHandler = new SessionAttributesHandler(handlerType, sessionAttributeStore);
this.sessionAttributesHandlerCache.put(handlerType, sessionAttrsHandler);
}
}
return handler.hasSessionAttributes();
FlashAttributesHandler flashAttrsHandler = null;
synchronized(this.flashAttributesHandlerCache) {
flashAttrsHandler = this.flashAttributesHandlerCache.get(handlerType);
if (flashAttrsHandler == null) {
flashAttrsHandler = new FlashAttributesHandler(handlerType);
this.flashAttributesHandlerCache.put(handlerType, flashAttrsHandler);
}
}
return sessionAttrsHandler.hasSessionAttributes() || flashAttrsHandler.hasFlashAttributes();
}
/**
@@ -509,12 +523,13 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
ServletWebRequest webRequest = new ServletWebRequest(request, response);
SessionStatus sessionStatus = new SimpleSessionStatus();
FlashStatus flashStatus = new SimpleFlashStatus();
ModelAndViewContainer mavContainer = new ModelAndViewContainer();
modelFactory.initModel(webRequest, mavContainer, requestMethod);
requestMethod.invokeAndHandle(webRequest, mavContainer, sessionStatus);
modelFactory.updateModel(webRequest, mavContainer, sessionStatus);
requestMethod.invokeAndHandle(webRequest, mavContainer, sessionStatus, flashStatus);
modelFactory.updateModel(webRequest, mavContainer, sessionStatus, flashStatus);
if (!mavContainer.isResolveView()) {
return null;
@@ -569,7 +584,10 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
modelAttrMethods.add(attrMethod);
}
return new ModelFactory(modelAttrMethods, binderFactory, sessionAttributesHandlerCache.get(handlerType));
SessionAttributesHandler sessionAttrsHandler = sessionAttributesHandlerCache.get(handlerType);
FlashAttributesHandler flashAttrsHandler = flashAttributesHandlerCache.get(handlerType);
return new ModelFactory(modelAttrMethods, binderFactory, sessionAttrsHandler, flashAttrsHandler);
}
private ServletInvocableHandlerMethod createRequestMappingMethod(HandlerMethod handlerMethod,

View File

@@ -0,0 +1,112 @@
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.mvc.method.annotation;
import static junit.framework.Assert.assertNotNull;
import javax.servlet.ServletException;
import org.junit.After;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.mock.web.MockServletConfig;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver;
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
/**
* Base class for tests using on the DispatcherServlet and HandlerMethod infrastructure classes:
* <ul>
* <li>RequestMappingHandlerMapping
* <li>RequestMappingHandlerAdapter
* <li>ExceptionHandlerExceptionResolver
* </ul>
*
* @author Rossen Stoyanchev
*/
public class AbstractServletHandlerMethodTests {
private DispatcherServlet servlet;
@After
public void tearDown() {
this.servlet = null;
}
protected DispatcherServlet getServlet() {
assertNotNull("DispatcherServlet not initialized", servlet);
return servlet;
}
/**
* Initialize a DispatcherServlet instance registering zero or more controller classes.
*/
protected WebApplicationContext initServletWithControllers(final Class<?>... controllerClasses)
throws ServletException {
return initServlet(null, controllerClasses);
}
/**
* Initialize a DispatcherServlet instance registering zero or more controller classes
* and also providing additional bean definitions through a callback.
*/
@SuppressWarnings("serial")
protected WebApplicationContext initServlet(
final ApplicationContextInitializer<GenericWebApplicationContext> initializer,
final Class<?>... controllerClasses) throws ServletException {
final GenericWebApplicationContext wac = new GenericWebApplicationContext();
servlet = new DispatcherServlet() {
@Override
protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) {
for (Class<?> clazz : controllerClasses) {
wac.registerBeanDefinition(clazz.getSimpleName(), new RootBeanDefinition(clazz));
}
Class<?> mappingType = RequestMappingHandlerMapping.class;
wac.registerBeanDefinition("handlerMapping", new RootBeanDefinition(mappingType));
Class<?> adapterType = RequestMappingHandlerAdapter.class;
wac.registerBeanDefinition("handlerAdapter", new RootBeanDefinition(adapterType));
Class<?> resolverType = ExceptionHandlerExceptionResolver.class;
wac.registerBeanDefinition("requestMappingResolver", new RootBeanDefinition(resolverType));
resolverType = ResponseStatusExceptionResolver.class;
wac.registerBeanDefinition("responseStatusResolver", new RootBeanDefinition(resolverType));
resolverType = DefaultHandlerExceptionResolver.class;
wac.registerBeanDefinition("defaultResolver", new RootBeanDefinition(resolverType));
if (initializer != null) {
initializer.initialize(wac);
}
wac.refresh();
return wac;
}
};
servlet.init(new MockServletConfig());
return wac;
}
}

View File

@@ -0,0 +1,215 @@
/*
* Copyright 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.web.servlet.mvc.method.annotation;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import java.util.Locale;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.Test;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.FlashAttributes;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.support.FlashStatus;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.method.annotation.FlashAttributesHandler;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
/**
* Test controllers with @{@link FlashAttributes} through the DispatcherServlet.
*
* @author Rossen Stoyanchev
*/
public class FlashAttributesServletTests extends AbstractServletHandlerMethodTests {
private static final String MESSAGE_KEY = "message";
@Test
public void successMessage() throws Exception {
initServletWithModelExposingViewResolver(MessageController.class);
MockHttpServletRequest req = new MockHttpServletRequest("GET", "/message");
MockHttpServletResponse res = new MockHttpServletResponse();
getServlet().service(req, res);
assertEquals(200, res.getStatus());
assertNull(getModelAttribute(req, MESSAGE_KEY));
assertNull(getFlashAttribute(req, MESSAGE_KEY));
req.setMethod("POST");
getServlet().service(req, res);
assertEquals(200, res.getStatus());
assertEquals("Yay!", ((Message) getModelAttribute(req, MESSAGE_KEY)).getText());
assertEquals("Yay!", ((Message) getFlashAttribute(req, MESSAGE_KEY)).getText());
req.setMethod("GET");
getServlet().service(req, res);
assertEquals(200, res.getStatus());
assertEquals("Yay!", ((Message) getModelAttribute(req, MESSAGE_KEY)).getText());
assertNull(getFlashAttribute(req, MESSAGE_KEY));
}
@Test
public void successMessageAcrossControllers() throws Exception {
initServletWithModelExposingViewResolver(MessageController.class, SecondMessageController.class);
MockHttpServletRequest req = new MockHttpServletRequest("POST", "/message");
MockHttpServletResponse res = new MockHttpServletResponse();
getServlet().service(req, res);
req.setParameter("another", "true");
getServlet().service(req, res);
assertEquals(200, res.getStatus());
assertEquals("Nay!", ((Message) getModelAttribute(req, MESSAGE_KEY)).getText());
assertEquals("Nay!", ((Message) getFlashAttribute(req, MESSAGE_KEY)).getText());
req.setMethod("GET");
req.setRequestURI("/second/message");
getServlet().service(req, res);
assertEquals(200, res.getStatus());
assertEquals("Nay!", ((Message) getModelAttribute(req, MESSAGE_KEY)).getText());
assertNull(getFlashAttribute(req, MESSAGE_KEY));
}
@Controller
@FlashAttributes("message")
static class MessageController {
@RequestMapping(value="/message", method=RequestMethod.GET)
public void message(Model model) {
}
@RequestMapping(value="/message", method=RequestMethod.POST)
public String sendMessage(Model model, FlashStatus status) {
status.setActive();
model.addAttribute(Message.success("Yay!"));
return "redirect:/message";
}
@RequestMapping(value="/message", method=RequestMethod.POST, params="another")
public String sendMessageToSecondController(Model model, FlashStatus status) {
status.setActive();
model.addAttribute(Message.error("Nay!"));
return "redirect:/second/message";
}
}
@Controller
static class SecondMessageController {
@RequestMapping(value="/second/message", method=RequestMethod.GET)
public void message(Model model) {
}
}
private static class Message {
private final MessageType type;
private final String text;
private Message(MessageType type, String text) {
this.type = type;
this.text = text;
}
public static Message success(String text) {
return new Message(MessageType.success, text);
}
public static Message error(String text) {
return new Message(MessageType.error, text);
}
public MessageType getType() {
return type;
}
public String getText() {
return text;
}
public String toString() {
return type + ": " + text;
}
}
private static enum MessageType {
info, success, warning, error
}
@SuppressWarnings("unchecked")
private Object getModelAttribute(MockHttpServletRequest req, String key) {
Map<String, ?> model = (Map<String, ?>) req.getAttribute(ModelExposingViewResolver.REQUEST_ATTRIBITE_MODEL);
return model.get(key);
}
@SuppressWarnings("unchecked")
private Object getFlashAttribute(MockHttpServletRequest req, String key) {
String flashAttributesKey = FlashAttributesHandler.FLASH_ATTRIBUTES_SESSION_KEY;
Map<String, Object> attrs = (Map<String, Object>) req.getSession().getAttribute(flashAttributesKey);
return (attrs != null) ? attrs.get(key) : null;
}
private WebApplicationContext initServletWithModelExposingViewResolver(Class<?>... controllerClasses)
throws ServletException {
return initServlet(new ApplicationContextInitializer<GenericWebApplicationContext>() {
public void initialize(GenericWebApplicationContext wac) {
wac.registerBeanDefinition("viewResolver", new RootBeanDefinition(ModelExposingViewResolver.class));
}
}, controllerClasses);
}
static class ModelExposingViewResolver implements ViewResolver {
static String REQUEST_ATTRIBITE_MODEL = "ModelExposingViewResolver.model";
public View resolveViewName(final String viewName, Locale locale) throws Exception {
return new View() {
public void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
request.setAttribute(REQUEST_ATTRIBITE_MODEL, model);
}
public String getContentType() {
return null;
}
};
}
}
}

View File

@@ -92,7 +92,7 @@ import org.springframework.web.servlet.mvc.method.annotation.support.ServletWebA
* <p>If you wish to add high-level tests, consider the following other "integration"-style tests:
* <ul>
* <li>{@link HandlerMethodAnnotationDetectionTests}
* <li>{@link ServletHandlerMethodTests}
* <li>{@link ServletAnnotationControllerHandlerMethodTests}
* </ul>
*
* @author Rossen Stoyanchev

View File

@@ -49,7 +49,7 @@ import org.springframework.web.servlet.mvc.method.annotation.support.ServletRequ
*
* <p>For higher-level adapter tests see:
* <ul>
* <li>{@link ServletHandlerMethodTests}
* <li>{@link ServletAnnotationControllerHandlerMethodTests}
* <li>{@link HandlerMethodAnnotationDetectionTests}
* <li>{@link RequestMappingHandlerAdapterIntegrationTests}
* </ul>

View File

@@ -28,16 +28,15 @@ import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.junit.Test;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletConfig;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
@@ -46,45 +45,51 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.View;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver;
import org.springframework.web.servlet.mvc.annotation.UriTemplateServletAnnotationControllerTests;
import org.springframework.web.servlet.mvc.annotation.UriTemplateServletAnnotationControllerTests.VariableNamesController;
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
import org.springframework.web.servlet.view.AbstractView;
/**
* The origin of this test class is {@link UriTemplateServletAnnotationControllerTests} with the tests in this class
* adapted to run against the HandlerMethod infrastructure rather than against the DefaultAnnotationHandlerMapping,
* the AnnotationMethodHandlerAdapter, and the AnnotationMethodHandlerExceptionResolver. Tests that are not supported
* are listed at the bottom.
*
* The origin of this test class is {@link UriTemplateServletAnnotationControllerTests}.
*
* Tests in this class run against the {@link HandlerMethod} infrastructure:
* <ul>
* <li>RequestMappingHandlerMapping
* <li>RequestMappingHandlerAdapter
* <li>ExceptionHandlerExceptionResolver
* </ul>
*
* <p>Rather than against the existing infrastructure:
* <ul>
* <li>DefaultAnnotationHandlerMapping
* <li>AnnotationMethodHandlerAdapter
* <li>AnnotationMethodHandlerExceptionResolver
* </ul>
*
* @author Rossen Stoyanchev
* @since 3.1
*/
public class UriTemplateServletHandlerMethodTests {
private DispatcherServlet servlet;
public class UriTemplateServletAnnotationControllerHandlerMethodTests extends AbstractServletHandlerMethodTests {
@Test
public void simple() throws Exception {
initDispatcherServlet(SimpleUriTemplateController.class, null);
initServletWithControllers(SimpleUriTemplateController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/42");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("test-42", response.getContentAsString());
}
@Test
public void multiple() throws Exception {
initDispatcherServlet(MultipleUriTemplateController.class, null);
initServletWithControllers(MultipleUriTemplateController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels/42/bookings/21-other");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("test-42-21-other", response.getContentAsString());
}
@@ -96,16 +101,16 @@ public class UriTemplateServletHandlerMethodTests {
pathVars.put("other", "other");
WebApplicationContext wac =
initDispatcherServlet(ViewRenderingController.class, new BeanDefinitionRegistrar() {
public void register(GenericWebApplicationContext context) {
initServlet(new ApplicationContextInitializer<GenericWebApplicationContext>() {
public void initialize(GenericWebApplicationContext context) {
RootBeanDefinition beanDef = new RootBeanDefinition(ModelValidatingViewResolver.class);
beanDef.getConstructorArgumentValues().addGenericArgumentValue(pathVars);
context.registerBeanDefinition("viewResolver", beanDef);
}
});
}, ViewRenderingController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels/42/bookings/21-other");
servlet.service(request, new MockHttpServletResponse());
getServlet().service(request, new MockHttpServletResponse());
ModelValidatingViewResolver resolver = wac.getBean(ModelValidatingViewResolver.class);
assertEquals(3, resolver.validatedAttrCount);
@@ -113,153 +118,153 @@ public class UriTemplateServletHandlerMethodTests {
@Test
public void binding() throws Exception {
initDispatcherServlet(BindingUriTemplateController.class, null);
initServletWithControllers(BindingUriTemplateController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels/42/dates/2008-11-18");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals(200, response.getStatus());
request = new MockHttpServletRequest("GET", "/hotels/42/dates/2008-foo-bar");
response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals(400, response.getStatus());
initDispatcherServlet(NonBindingUriTemplateController.class, null);
initServletWithControllers(NonBindingUriTemplateController.class);
request = new MockHttpServletRequest("GET", "/hotels/42/dates/2008-foo-bar");
response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals(500, response.getStatus());
}
@Test
public void ambiguous() throws Exception {
initDispatcherServlet(AmbiguousUriTemplateController.class, null);
initServletWithControllers(AmbiguousUriTemplateController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels/new");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("specific", response.getContentAsString());
}
@Test
public void relative() throws Exception {
initDispatcherServlet(RelativePathUriTemplateController.class, null);
initServletWithControllers(RelativePathUriTemplateController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels/42/bookings/21");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("test-42-21", response.getContentAsString());
request = new MockHttpServletRequest("GET", "/hotels/42/bookings/21.html");
response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("test-42-21", response.getContentAsString());
}
@Test
public void extension() throws Exception {
initDispatcherServlet(SimpleUriTemplateController.class, null);
initServletWithControllers(SimpleUriTemplateController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/42.xml");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("test-42", response.getContentAsString());
}
@Test
public void typeConversionError() throws Exception {
initDispatcherServlet(SimpleUriTemplateController.class, null);
initServletWithControllers(SimpleUriTemplateController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo.xml");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("Invalid response status code", HttpServletResponse.SC_BAD_REQUEST, response.getStatus());
}
@Test
public void explicitSubPath() throws Exception {
initDispatcherServlet(ExplicitSubPathController.class, null);
initServletWithControllers(ExplicitSubPathController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels/42");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("test-42", response.getContentAsString());
}
@Test
public void implicitSubPath() throws Exception {
initDispatcherServlet(ImplicitSubPathController.class, null);
initServletWithControllers(ImplicitSubPathController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels/42");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("test-42", response.getContentAsString());
}
@Test
public void crud() throws Exception {
initDispatcherServlet(CrudController.class, null);
initServletWithControllers(CrudController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("list", response.getContentAsString());
request = new MockHttpServletRequest("GET", "/hotels/");
response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("list", response.getContentAsString());
request = new MockHttpServletRequest("POST", "/hotels");
response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("create", response.getContentAsString());
request = new MockHttpServletRequest("GET", "/hotels/42");
response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("show-42", response.getContentAsString());
request = new MockHttpServletRequest("GET", "/hotels/42/");
response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("show-42", response.getContentAsString());
request = new MockHttpServletRequest("PUT", "/hotels/42");
response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("createOrUpdate-42", response.getContentAsString());
request = new MockHttpServletRequest("DELETE", "/hotels/42");
response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("remove-42", response.getContentAsString());
}
@Test
public void methodNotSupported() throws Exception {
initDispatcherServlet(MethodNotAllowedController.class, null);
initServletWithControllers(MethodNotAllowedController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/hotels/1");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals(200, response.getStatus());
request = new MockHttpServletRequest("POST", "/hotels/1");
response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals(405, response.getStatus());
request = new MockHttpServletRequest("GET", "/hotels");
response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals(200, response.getStatus());
request = new MockHttpServletRequest("POST", "/hotels");
response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals(405, response.getStatus());
@@ -267,26 +272,26 @@ public class UriTemplateServletHandlerMethodTests {
@Test
public void multiPaths() throws Exception {
initDispatcherServlet(MultiPathController.class, null);
initServletWithControllers(MultiPathController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/category/page/5");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("handle4-page-5", response.getContentAsString());
request = new MockHttpServletRequest("GET", "/category/page/5.html");
response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("handle4-page-5", response.getContentAsString());
}
@Test
public void customRegex() throws Exception {
initDispatcherServlet(CustomRegexController.class, null);
initServletWithControllers(CustomRegexController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/42");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("test-42", response.getContentAsString());
}
@@ -295,11 +300,11 @@ public class UriTemplateServletHandlerMethodTests {
*/
@Test
public void menuTree() throws Exception {
initDispatcherServlet(MenuTreeController.class, null);
initServletWithControllers(MenuTreeController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/book/menu/type/M5");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("M5", response.getContentAsString());
}
@@ -308,16 +313,16 @@ public class UriTemplateServletHandlerMethodTests {
*/
@Test
public void variableNames() throws Exception {
initDispatcherServlet(VariableNamesController.class, null);
initServletWithControllers(VariableNamesController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/test/foo");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("foo-foo", response.getContentAsString());
request = new MockHttpServletRequest("DELETE", "/test/bar");
response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("bar-bar", response.getContentAsString());
}
@@ -326,11 +331,11 @@ public class UriTemplateServletHandlerMethodTests {
*/
@Test
public void variableNamesWithUrlExtension() throws Exception {
initDispatcherServlet(VariableNamesController.class, null);
initServletWithControllers(VariableNamesController.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/test/foo.json");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("foo-foo", response.getContentAsString());
}
@@ -339,26 +344,26 @@ public class UriTemplateServletHandlerMethodTests {
*/
@Test
public void doIt() throws Exception {
initDispatcherServlet(Spr6978Controller.class, null);
initServletWithControllers(Spr6978Controller.class);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo/100");
MockHttpServletResponse response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("loadEntity:foo:100", response.getContentAsString());
request = new MockHttpServletRequest("POST", "/foo/100");
response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("publish:foo:100", response.getContentAsString());
request = new MockHttpServletRequest("GET", "/module/100");
response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("loadModule:100", response.getContentAsString());
request = new MockHttpServletRequest("POST", "/module/100");
response = new MockHttpServletResponse();
servlet.service(request, response);
getServlet().service(request, response);
assertEquals("publish:module:100", response.getContentAsString());
}
@@ -672,50 +677,6 @@ public class UriTemplateServletHandlerMethodTests {
}
}
private interface BeanDefinitionRegistrar {
public void register(GenericWebApplicationContext context);
}
@SuppressWarnings("serial")
private WebApplicationContext initDispatcherServlet(final Class<?> controllerClass, final BeanDefinitionRegistrar registrar)
throws ServletException {
final GenericWebApplicationContext wac = new GenericWebApplicationContext();
servlet = new DispatcherServlet() {
@Override
protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) {
wac.registerBeanDefinition("controller", new RootBeanDefinition(controllerClass));
Class<?> mappingType = RequestMappingHandlerMapping.class;
wac.registerBeanDefinition("handlerMapping", new RootBeanDefinition(mappingType));
Class<?> adapterType = RequestMappingHandlerAdapter.class;
wac.registerBeanDefinition("handlerAdapter", new RootBeanDefinition(adapterType));
Class<?> resolverType = ExceptionHandlerExceptionResolver.class;
wac.registerBeanDefinition("requestMappingResolver", new RootBeanDefinition(resolverType));
resolverType = ResponseStatusExceptionResolver.class;
wac.registerBeanDefinition("responseStatusResolver", new RootBeanDefinition(resolverType));
resolverType = DefaultHandlerExceptionResolver.class;
wac.registerBeanDefinition("defaultResolver", new RootBeanDefinition(resolverType));
if (registrar != null) {
registrar.register(wac);
}
wac.refresh();
return wac;
}
};
servlet.init(new MockServletConfig());
return wac;
}
// @Ignore("ControllerClassNameHandlerMapping")
// public void controllerClassName() throws Exception {