diff --git a/org.springframework.testsuite/src/test/java/org/springframework/web/context/request/requestScopeTests.xml b/org.springframework.testsuite/src/test/java/org/springframework/web/context/request/requestScopeTests.xml deleted file mode 100644 index badc6d6cf2..0000000000 --- a/org.springframework.testsuite/src/test/java/org/springframework/web/context/request/requestScopeTests.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.springframework.testsuite/src/test/java/org/springframework/web/context/request/requestScopedProxyTests.xml b/org.springframework.testsuite/src/test/java/org/springframework/web/context/request/requestScopedProxyTests.xml deleted file mode 100644 index ee1313d4dc..0000000000 --- a/org.springframework.testsuite/src/test/java/org/springframework/web/context/request/requestScopedProxyTests.xml +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.springframework.testsuite/src/test/java/org/springframework/web/context/request/sessionScopeTests.xml b/org.springframework.testsuite/src/test/java/org/springframework/web/context/request/sessionScopeTests.xml deleted file mode 100644 index e4f05b9abe..0000000000 --- a/org.springframework.testsuite/src/test/java/org/springframework/web/context/request/sessionScopeTests.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/org.springframework.testsuite/src/test/java/org/springframework/web/servlet/mvc/annotation/ControllerClassNameHandlerMappingTests.java b/org.springframework.testsuite/src/test/java/org/springframework/web/servlet/mvc/annotation/ControllerClassNameHandlerMappingTests.java deleted file mode 100644 index ec3bd838dd..0000000000 --- a/org.springframework.testsuite/src/test/java/org/springframework/web/servlet/mvc/annotation/ControllerClassNameHandlerMappingTests.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2002-2008 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.servlet.mvc.annotation; - -import junit.framework.TestCase; - -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockServletContext; -import org.springframework.web.context.support.XmlWebApplicationContext; -import org.springframework.web.servlet.HandlerExecutionChain; -import org.springframework.web.servlet.HandlerMapping; - -/** - * @author Juergen Hoeller - */ -public class ControllerClassNameHandlerMappingTests extends TestCase { - - public static final String LOCATION = "/org/springframework/web/servlet/mvc/annotation/class-mapping.xml"; - - private XmlWebApplicationContext wac; - - private HandlerMapping hm; - - private HandlerMapping hm2; - - private HandlerMapping hm3; - - private HandlerMapping hm4; - - public void setUp() throws Exception { - MockServletContext sc = new MockServletContext(""); - this.wac = new XmlWebApplicationContext(); - this.wac.setServletContext(sc); - this.wac.setConfigLocations(new String[] {LOCATION}); - this.wac.refresh(); - this.hm = (HandlerMapping) this.wac.getBean("mapping"); - this.hm2 = (HandlerMapping) this.wac.getBean("mapping2"); - this.hm3 = (HandlerMapping) this.wac.getBean("mapping3"); - this.hm4 = (HandlerMapping) this.wac.getBean("mapping4"); - } - - public void testIndexUri() throws Exception { - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/index"); - HandlerExecutionChain chain = this.hm.getHandler(request); - assertEquals(this.wac.getBean("index"), chain.getHandler()); - - request = new MockHttpServletRequest("GET", "/index/product"); - chain = this.hm.getHandler(request); - assertEquals(this.wac.getBean("index"), chain.getHandler()); - } - - public void testMapSimpleUri() throws Exception { - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/welcome"); - HandlerExecutionChain chain = this.hm.getHandler(request); - assertEquals(this.wac.getBean("welcome"), chain.getHandler()); - - request = new MockHttpServletRequest("GET", "/welcome/product"); - chain = this.hm.getHandler(request); - assertEquals(this.wac.getBean("welcome"), chain.getHandler()); - } - - public void testWithContextPath() throws Exception { - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myapp/welcome"); - request.setContextPath("/myapp"); - HandlerExecutionChain chain = this.hm.getHandler(request); - assertEquals(this.wac.getBean("welcome"), chain.getHandler()); - } - - public void testWithoutControllerSuffix() throws Exception { - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/buyform"); - HandlerExecutionChain chain = this.hm.getHandler(request); - assertEquals(this.wac.getBean("buy"), chain.getHandler()); - - request = new MockHttpServletRequest("GET", "/buyform/product"); - chain = this.hm.getHandler(request); - assertEquals(this.wac.getBean("buy"), chain.getHandler()); - } - - public void testWithBasePackage() throws Exception { - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myapp/mvc/annotation/welcome"); - HandlerExecutionChain chain = this.hm2.getHandler(request); - assertEquals(this.wac.getBean("welcome"), chain.getHandler()); - } - - public void testWithBasePackageAndCaseSensitive() throws Exception { - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myapp/mvc/annotation/buyForm"); - HandlerExecutionChain chain = this.hm2.getHandler(request); - assertEquals(this.wac.getBean("buy"), chain.getHandler()); - } - - public void testWithFullBasePackage() throws Exception { - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myapp/welcome"); - HandlerExecutionChain chain = this.hm3.getHandler(request); - assertEquals(this.wac.getBean("welcome"), chain.getHandler()); - } - - public void testWithRootAsBasePackage() throws Exception { - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myapp/org/springframework/web/servlet/mvc/annotation/welcome"); - HandlerExecutionChain chain = this.hm4.getHandler(request); - assertEquals(this.wac.getBean("welcome"), chain.getHandler()); - } - -} \ No newline at end of file diff --git a/org.springframework.testsuite/src/test/java/org/springframework/web/servlet/mvc/annotation/ServletAnnotationControllerTests.java b/org.springframework.testsuite/src/test/java/org/springframework/web/servlet/mvc/annotation/ServletAnnotationControllerTests.java deleted file mode 100644 index 78fb102d3a..0000000000 --- a/org.springframework.testsuite/src/test/java/org/springframework/web/servlet/mvc/annotation/ServletAnnotationControllerTests.java +++ /dev/null @@ -1,1137 +0,0 @@ -/* - * Copyright 2002-2008 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.servlet.mvc.annotation; - -import java.io.IOException; -import java.io.Writer; -import java.security.Principal; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.LinkedList; -import java.util.List; -import java.util.Locale; -import java.util.Map; - -import javax.servlet.ServletConfig; -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import junit.framework.TestCase; - -import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; -import org.springframework.aop.interceptor.SimpleTraceInterceptor; -import org.springframework.aop.support.DefaultPointcutAdvisor; -import org.springframework.beans.DerivedTestBean; -import org.springframework.beans.ITestBean; -import org.springframework.beans.TestBean; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.support.RootBeanDefinition; -import org.springframework.beans.propertyeditors.CustomDateEditor; -import org.springframework.context.annotation.AnnotationConfigUtils; -import org.springframework.core.MethodParameter; -import org.springframework.mock.web.MockHttpServletRequest; -import org.springframework.mock.web.MockHttpServletResponse; -import org.springframework.mock.web.MockServletConfig; -import org.springframework.mock.web.MockServletContext; -import org.springframework.stereotype.Controller; -import org.springframework.ui.ExtendedModelMap; -import org.springframework.ui.Model; -import org.springframework.ui.ModelMap; -import org.springframework.validation.BindingResult; -import org.springframework.validation.Errors; -import org.springframework.web.bind.WebDataBinder; -import org.springframework.web.bind.annotation.InitBinder; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.support.WebArgumentResolver; -import org.springframework.web.bind.support.WebBindingInitializer; -import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.context.request.NativeWebRequest; -import org.springframework.web.context.request.WebRequest; -import org.springframework.web.context.support.GenericWebApplicationContext; -import org.springframework.web.servlet.DispatcherServlet; -import org.springframework.web.servlet.ModelAndView; -import org.springframework.web.servlet.View; -import org.springframework.web.servlet.ViewResolver; -import org.springframework.web.servlet.mvc.AbstractController; -import org.springframework.web.servlet.mvc.multiaction.InternalPathMethodNameResolver; -import org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping; -import org.springframework.web.servlet.view.InternalResourceViewResolver; -import org.springframework.web.util.NestedServletException; - -/** - * @author Juergen Hoeller - * @author Sam Brannen - * @since 2.5 - */ -public class ServletAnnotationControllerTests extends TestCase { - - public void testStandardHandleMethod() throws Exception { - @SuppressWarnings("serial") - DispatcherServlet servlet = new DispatcherServlet() { - protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) { - GenericWebApplicationContext wac = new GenericWebApplicationContext(); - wac.registerBeanDefinition("controller", new RootBeanDefinition(MyController.class)); - wac.refresh(); - return wac; - } - }; - servlet.init(new MockServletConfig()); - - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myPath.do"); - MockHttpServletResponse response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("test", response.getContentAsString()); - } - - public void testProxiedStandardHandleMethod() throws Exception { - DispatcherServlet servlet = new DispatcherServlet() { - protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) { - GenericWebApplicationContext wac = new GenericWebApplicationContext(); - wac.registerBeanDefinition("controller", new RootBeanDefinition(MyController.class)); - DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator(); - autoProxyCreator.setBeanFactory(wac.getBeanFactory()); - wac.getBeanFactory().addBeanPostProcessor(autoProxyCreator); - wac.getBeanFactory().registerSingleton("advisor", new DefaultPointcutAdvisor(new SimpleTraceInterceptor())); - wac.refresh(); - return wac; - } - }; - servlet.init(new MockServletConfig()); - - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myPath.do"); - MockHttpServletResponse response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("test", response.getContentAsString()); - } - - public void testEmptyParameterListHandleMethod() throws Exception { - @SuppressWarnings("serial") - DispatcherServlet servlet = new DispatcherServlet() { - protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) { - GenericWebApplicationContext wac = new GenericWebApplicationContext(); - wac.registerBeanDefinition("controller", new RootBeanDefinition(EmptyParameterListHandlerMethodController.class)); - RootBeanDefinition vrDef = new RootBeanDefinition(InternalResourceViewResolver.class); - vrDef.getPropertyValues().addPropertyValue("suffix", ".jsp"); - wac.registerBeanDefinition("viewResolver", vrDef); - wac.refresh(); - return wac; - } - }; - servlet.init(new MockServletConfig()); - - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/emptyParameterListHandler"); - MockHttpServletResponse response = new MockHttpServletResponse(); - - EmptyParameterListHandlerMethodController.called = false; - servlet.service(request, response); - assertTrue(EmptyParameterListHandlerMethodController.called); - assertEquals("", response.getContentAsString()); - } - - public void testAdaptedHandleMethods() throws Exception { - doTestAdaptedHandleMethods(MyAdaptedController.class); - } - - public void testAdaptedHandleMethods2() throws Exception { - doTestAdaptedHandleMethods(MyAdaptedController2.class); - } - - public void testAdaptedHandleMethods3() throws Exception { - doTestAdaptedHandleMethods(MyAdaptedController3.class); - } - - private void doTestAdaptedHandleMethods(final Class controllerClass) throws Exception { - @SuppressWarnings("serial") - DispatcherServlet servlet = new DispatcherServlet() { - protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) { - GenericWebApplicationContext wac = new GenericWebApplicationContext(); - wac.registerBeanDefinition("controller", new RootBeanDefinition(controllerClass)); - wac.refresh(); - return wac; - } - }; - servlet.init(new MockServletConfig()); - - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myPath1.do"); - MockHttpServletResponse response = new MockHttpServletResponse(); - request.addParameter("param1", "value1"); - request.addParameter("param2", "2"); - servlet.service(request, response); - assertEquals("test", response.getContentAsString()); - - request = new MockHttpServletRequest("GET", "/myPath2.do"); - request.addParameter("param1", "value1"); - request.addParameter("param2", "2"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("test-value1-2", response.getContentAsString()); - - request = new MockHttpServletRequest("GET", "/myPath3.do"); - request.addParameter("param1", "value1"); - request.addParameter("param2", "2"); - request.addParameter("name", "name1"); - request.addParameter("age", "2"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("test-name1-2", response.getContentAsString()); - - request = new MockHttpServletRequest("GET", "/myPath4.do"); - request.addParameter("param1", "value1"); - request.addParameter("param2", "2"); - request.addParameter("name", "name1"); - request.addParameter("age", "value2"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("test-name1-typeMismatch", response.getContentAsString()); - } - - public void testFormController() throws Exception { - @SuppressWarnings("serial") - DispatcherServlet servlet = new DispatcherServlet() { - protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) { - GenericWebApplicationContext wac = new GenericWebApplicationContext(); - wac.registerBeanDefinition("controller", new RootBeanDefinition(MyFormController.class)); - wac.registerBeanDefinition("viewResolver", new RootBeanDefinition(TestViewResolver.class)); - wac.refresh(); - return wac; - } - }; - servlet.init(new MockServletConfig()); - - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myPath.do"); - request.addParameter("name", "name1"); - request.addParameter("age", "value2"); - MockHttpServletResponse response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myView-name1-typeMismatch-tb1-myValue", response.getContentAsString()); - } - - public void testModelFormController() throws Exception { - @SuppressWarnings("serial") - DispatcherServlet servlet = new DispatcherServlet() { - protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) { - GenericWebApplicationContext wac = new GenericWebApplicationContext(); - wac.registerBeanDefinition("controller", new RootBeanDefinition(MyModelFormController.class)); - wac.registerBeanDefinition("viewResolver", new RootBeanDefinition(TestViewResolver.class)); - wac.refresh(); - return wac; - } - }; - servlet.init(new MockServletConfig()); - - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myPath.do"); - request.addParameter("name", "name1"); - request.addParameter("age", "value2"); - MockHttpServletResponse response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myView-name1-typeMismatch-tb1-myValue", response.getContentAsString()); - } - - public void testProxiedFormController() throws Exception { - DispatcherServlet servlet = new DispatcherServlet() { - protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) { - GenericWebApplicationContext wac = new GenericWebApplicationContext(); - wac.registerBeanDefinition("controller", new RootBeanDefinition(MyFormController.class)); - wac.registerBeanDefinition("viewResolver", new RootBeanDefinition(TestViewResolver.class)); - DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator(); - autoProxyCreator.setBeanFactory(wac.getBeanFactory()); - wac.getBeanFactory().addBeanPostProcessor(autoProxyCreator); - wac.getBeanFactory().registerSingleton("advisor", new DefaultPointcutAdvisor(new SimpleTraceInterceptor())); - wac.refresh(); - return wac; - } - }; - servlet.init(new MockServletConfig()); - - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myPath.do"); - request.addParameter("name", "name1"); - request.addParameter("age", "value2"); - MockHttpServletResponse response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myView-name1-typeMismatch-tb1-myValue", response.getContentAsString()); - } - - public void testCommandProvidingFormController() throws Exception { - @SuppressWarnings("serial") - DispatcherServlet servlet = new DispatcherServlet() { - protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) { - GenericWebApplicationContext wac = new GenericWebApplicationContext(); - wac.registerBeanDefinition("controller", new RootBeanDefinition(MyCommandProvidingFormController.class)); - wac.registerBeanDefinition("viewResolver", new RootBeanDefinition(TestViewResolver.class)); - RootBeanDefinition adapterDef = new RootBeanDefinition(AnnotationMethodHandlerAdapter.class); - adapterDef.getPropertyValues().addPropertyValue("webBindingInitializer", new MyWebBindingInitializer()); - wac.registerBeanDefinition("handlerAdapter", adapterDef); - wac.refresh(); - return wac; - } - }; - servlet.init(new MockServletConfig()); - - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myPath.do"); - request.addParameter("defaultName", "myDefaultName"); - request.addParameter("age", "value2"); - request.addParameter("date", "2007-10-02"); - MockHttpServletResponse response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myView-String:myDefaultName-typeMismatch-tb1-myOriginalValue", response.getContentAsString()); - } - - public void testTypedCommandProvidingFormController() throws Exception { - @SuppressWarnings("serial") - DispatcherServlet servlet = new DispatcherServlet() { - protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) { - GenericWebApplicationContext wac = new GenericWebApplicationContext(); - wac.registerBeanDefinition("controller", new RootBeanDefinition(MyTypedCommandProvidingFormController.class)); - wac.registerBeanDefinition("viewResolver", new RootBeanDefinition(TestViewResolver.class)); - RootBeanDefinition adapterDef = new RootBeanDefinition(AnnotationMethodHandlerAdapter.class); - adapterDef.getPropertyValues().addPropertyValue("webBindingInitializer", new MyWebBindingInitializer()); - adapterDef.getPropertyValues().addPropertyValue("customArgumentResolver", new MySpecialArgumentResolver()); - wac.registerBeanDefinition("handlerAdapter", adapterDef); - wac.refresh(); - return wac; - } - }; - servlet.init(new MockServletConfig()); - - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myPath.do"); - request.addParameter("defaultName", "10"); - request.addParameter("age", "value2"); - request.addParameter("date", "2007-10-02"); - MockHttpServletResponse response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myView-Integer:10-typeMismatch-tb1-myOriginalValue", response.getContentAsString()); - - request = new MockHttpServletRequest("GET", "/myOtherPath.do"); - request.addParameter("defaultName", "10"); - request.addParameter("age", "value2"); - request.addParameter("date", "2007-10-02"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myView-myName-typeMismatch-tb1-myOriginalValue", response.getContentAsString()); - - request = new MockHttpServletRequest("GET", "/myThirdPath.do"); - request.addParameter("defaultName", "10"); - request.addParameter("age", "100"); - request.addParameter("date", "2007-10-02"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myView-special-99-special-99", response.getContentAsString()); - } - - public void testBinderInitializingCommandProvidingFormController() throws Exception { - @SuppressWarnings("serial") - DispatcherServlet servlet = new DispatcherServlet() { - protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) { - GenericWebApplicationContext wac = new GenericWebApplicationContext(); - wac.registerBeanDefinition("controller", new RootBeanDefinition(MyBinderInitializingCommandProvidingFormController.class)); - wac.registerBeanDefinition("viewResolver", new RootBeanDefinition(TestViewResolver.class)); - wac.refresh(); - return wac; - } - }; - servlet.init(new MockServletConfig()); - - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myPath.do"); - request.addParameter("defaultName", "myDefaultName"); - request.addParameter("age", "value2"); - request.addParameter("date", "2007-10-02"); - MockHttpServletResponse response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myView-String:myDefaultName-typeMismatch-tb1-myOriginalValue", response.getContentAsString()); - } - - public void testSpecificBinderInitializingCommandProvidingFormController() throws Exception { - @SuppressWarnings("serial") - DispatcherServlet servlet = new DispatcherServlet() { - protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) { - GenericWebApplicationContext wac = new GenericWebApplicationContext(); - wac.registerBeanDefinition("controller", new RootBeanDefinition(MySpecificBinderInitializingCommandProvidingFormController.class)); - wac.registerBeanDefinition("viewResolver", new RootBeanDefinition(TestViewResolver.class)); - wac.refresh(); - return wac; - } - }; - servlet.init(new MockServletConfig()); - - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myPath.do"); - request.addParameter("defaultName", "myDefaultName"); - request.addParameter("age", "value2"); - request.addParameter("date", "2007-10-02"); - MockHttpServletResponse response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myView-String:myDefaultName-typeMismatch-tb1-myOriginalValue", response.getContentAsString()); - } - - public void testParameterDispatchingController() throws Exception { - final MockServletContext servletContext = new MockServletContext(); - final MockServletConfig servletConfig = new MockServletConfig(servletContext); - - @SuppressWarnings("serial") - DispatcherServlet servlet = new DispatcherServlet() { - protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) { - GenericWebApplicationContext wac = new GenericWebApplicationContext(); - wac.setServletContext(servletContext); - RootBeanDefinition bd = new RootBeanDefinition(MyParameterDispatchingController.class); - bd.setScope(WebApplicationContext.SCOPE_REQUEST); - wac.registerBeanDefinition("controller", bd); - AnnotationConfigUtils.registerAnnotationConfigProcessors(wac); - wac.getBeanFactory().registerResolvableDependency(ServletConfig.class, servletConfig); - wac.refresh(); - return wac; - } - }; - servlet.init(servletConfig); - - MockHttpServletRequest request = new MockHttpServletRequest(servletContext, "GET", "/myPath.do"); - MockHttpServletResponse response = new MockHttpServletResponse(); - HttpSession session = request.getSession(); - servlet.service(request, response); - assertEquals("myView", response.getContentAsString()); - assertSame(servletContext, request.getAttribute("servletContext")); - assertSame(servletConfig, request.getAttribute("servletConfig")); - assertSame(session, request.getAttribute("session")); - assertSame(request, request.getAttribute("request")); - - request = new MockHttpServletRequest(servletContext, "GET", "/myPath.do"); - response = new MockHttpServletResponse(); - session = request.getSession(); - servlet.service(request, response); - assertEquals("myView", response.getContentAsString()); - assertSame(servletContext, request.getAttribute("servletContext")); - assertSame(servletConfig, request.getAttribute("servletConfig")); - assertSame(session, request.getAttribute("session")); - assertSame(request, request.getAttribute("request")); - - request = new MockHttpServletRequest(servletContext, "GET", "/myPath.do"); - request.addParameter("view", "other"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myOtherView", response.getContentAsString()); - - request = new MockHttpServletRequest(servletContext, "GET", "/myPath.do"); - request.addParameter("view", "my"); - request.addParameter("lang", "de"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myLangView", response.getContentAsString()); - - request = new MockHttpServletRequest(servletContext, "GET", "/myPath.do"); - request.addParameter("surprise", "!"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("mySurpriseView", response.getContentAsString()); - } - - public void testMethodNameDispatchingController() throws Exception { - @SuppressWarnings("serial") - DispatcherServlet servlet = new DispatcherServlet() { - protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) { - GenericWebApplicationContext wac = new GenericWebApplicationContext(); - wac.registerBeanDefinition("controller", new RootBeanDefinition(MethodNameDispatchingController.class)); - wac.refresh(); - return wac; - } - }; - servlet.init(new MockServletConfig()); - - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myHandle.do"); - MockHttpServletResponse response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myView", response.getContentAsString()); - - request = new MockHttpServletRequest("GET", "/myOtherHandle.do"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myOtherView", response.getContentAsString()); - - request = new MockHttpServletRequest("POST", "/myLangHandle.do"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myLangView", response.getContentAsString()); - - request = new MockHttpServletRequest("POST", "/mySurpriseHandle.do"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("mySurpriseView", response.getContentAsString()); - } - - public void testMethodNameDispatchingControllerWithSuffix() throws Exception { - @SuppressWarnings("serial") - DispatcherServlet servlet = new DispatcherServlet() { - protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) { - GenericWebApplicationContext wac = new GenericWebApplicationContext(); - wac.registerBeanDefinition("controller", new RootBeanDefinition(MethodNameDispatchingController.class)); - InternalPathMethodNameResolver methodNameResolver = new InternalPathMethodNameResolver(); - methodNameResolver.setSuffix("Handle"); - RootBeanDefinition adapterDef = new RootBeanDefinition(AnnotationMethodHandlerAdapter.class); - adapterDef.getPropertyValues().addPropertyValue("methodNameResolver", methodNameResolver); - wac.registerBeanDefinition("handlerAdapter", adapterDef); - wac.refresh(); - return wac; - } - }; - servlet.init(new MockServletConfig()); - - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/my.do"); - MockHttpServletResponse response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myView", response.getContentAsString()); - - request = new MockHttpServletRequest("GET", "/myOther.do"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myOtherView", response.getContentAsString()); - - request = new MockHttpServletRequest("POST", "/myLang.do"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myLangView", response.getContentAsString()); - - request = new MockHttpServletRequest("POST", "/mySurprise.do"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("mySurpriseView", response.getContentAsString()); - } - - public void testControllerClassNamePlusMethodNameDispatchingController() throws Exception { - @SuppressWarnings("serial") - DispatcherServlet servlet = new DispatcherServlet() { - protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) { - GenericWebApplicationContext wac = new GenericWebApplicationContext(); - RootBeanDefinition mapping = new RootBeanDefinition(ControllerClassNameHandlerMapping.class); - mapping.getPropertyValues().addPropertyValue("excludedPackages", null); - wac.registerBeanDefinition("handlerMapping", mapping); - wac.registerBeanDefinition("controller", new RootBeanDefinition(MethodNameDispatchingController.class)); - wac.refresh(); - return wac; - } - }; - servlet.init(new MockServletConfig()); - - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/methodnamedispatching/myHandle"); - MockHttpServletResponse response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myView", response.getContentAsString()); - - request = new MockHttpServletRequest("GET", "/methodnamedispatching/myOtherHandle.do"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myOtherView", response.getContentAsString()); - - request = new MockHttpServletRequest("POST", "/methodnamedispatching/myLangHandle.x"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myLangView", response.getContentAsString()); - - request = new MockHttpServletRequest("POST", "/methodnamedispatching/mySurpriseHandle.y"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("mySurpriseView", response.getContentAsString()); - } - - public void testPostMethodNameDispatchingController() throws Exception { - @SuppressWarnings("serial") - DispatcherServlet servlet = new DispatcherServlet() { - protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) { - GenericWebApplicationContext wac = new GenericWebApplicationContext(); - wac.registerBeanDefinition("controller", new RootBeanDefinition(MyPostMethodNameDispatchingController.class)); - wac.refresh(); - return wac; - } - }; - servlet.init(new MockServletConfig()); - - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myHandle.do"); - MockHttpServletResponse response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals(405, response.getStatus()); - - request = new MockHttpServletRequest("POST", "/myUnknownHandle.do"); - request.addParameter("myParam", "myValue"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals(404, response.getStatus()); - - request = new MockHttpServletRequest("POST", "/myHandle.do"); - request.addParameter("myParam", "myValue"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myView", response.getContentAsString()); - - request = new MockHttpServletRequest("POST", "/myOtherHandle.do"); - request.addParameter("myParam", "myValue"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myOtherView", response.getContentAsString()); - - request = new MockHttpServletRequest("POST", "/myLangHandle.do"); - request.addParameter("myParam", "myValue"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myLangView", response.getContentAsString()); - - request = new MockHttpServletRequest("POST", "/mySurpriseHandle.do"); - request.addParameter("myParam", "myValue"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("mySurpriseView", response.getContentAsString()); - } - - public void testRelativePathDispatchingController() throws Exception { - @SuppressWarnings("serial") - DispatcherServlet servlet = new DispatcherServlet() { - protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) { - GenericWebApplicationContext wac = new GenericWebApplicationContext(); - wac.registerBeanDefinition("controller", new RootBeanDefinition(MyRelativePathDispatchingController.class)); - wac.refresh(); - return wac; - } - }; - servlet.init(new MockServletConfig()); - - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myApp/myHandle"); - MockHttpServletResponse response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myView", response.getContentAsString()); - - request = new MockHttpServletRequest("GET", "/myApp/myOther"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myOtherView", response.getContentAsString()); - - request = new MockHttpServletRequest("GET", "/myApp/myLang"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myLangView", response.getContentAsString()); - - request = new MockHttpServletRequest("GET", "/myApp/surprise.do"); - response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("mySurpriseView", response.getContentAsString()); - } - - public void testNullCommandController() throws Exception { - @SuppressWarnings("serial") - DispatcherServlet servlet = new DispatcherServlet() { - protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) { - GenericWebApplicationContext wac = new GenericWebApplicationContext(); - wac.registerBeanDefinition("controller", new RootBeanDefinition(MyNullCommandController.class)); - wac.refresh(); - return wac; - } - }; - servlet.init(new MockServletConfig()); - - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/myPath"); - request.setUserPrincipal(new OtherPrincipal()); - MockHttpServletResponse response = new MockHttpServletResponse(); - servlet.service(request, response); - assertEquals("myView", response.getContentAsString()); - } - - public void testEquivalentMappingsWithSameMethodName() throws Exception { - @SuppressWarnings("serial") - DispatcherServlet servlet = new DispatcherServlet() { - protected WebApplicationContext createWebApplicationContext(WebApplicationContext parent) { - GenericWebApplicationContext wac = new GenericWebApplicationContext(); - wac.registerBeanDefinition("controller", new RootBeanDefinition(ChildController.class)); - wac.refresh(); - return wac; - } - }; - servlet.init(new MockServletConfig()); - - MockHttpServletRequest request = new MockHttpServletRequest("GET", "/child/test"); - request.addParameter("childId", "100"); - MockHttpServletResponse response = new MockHttpServletResponse(); - try { - servlet.service(request, response); - } - catch (NestedServletException ex) { - assertTrue(ex.getCause() instanceof IllegalStateException); - assertTrue(ex.getCause().getMessage().contains("doGet")); - } - } - - - @RequestMapping("/myPath.do") - private static class MyController extends AbstractController { - - protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception { - response.getWriter().write("test"); - return null; - } - } - - - private static class BaseController { - - @RequestMapping(method = RequestMethod.GET) - public void myPath2(HttpServletResponse response) throws IOException { - response.getWriter().write("test"); - } - } - - - @Controller - private static class MyAdaptedController { - - @RequestMapping("/myPath1.do") - public void myHandle(HttpServletRequest request, HttpServletResponse response) throws IOException { - response.getWriter().write("test"); - } - - @RequestMapping("/myPath2.do") - public void myHandle(@RequestParam("param1") String p1, @RequestParam("param2") int p2, HttpServletResponse response) throws IOException { - response.getWriter().write("test-" + p1 + "-" + p2); - } - - @RequestMapping("/myPath3") - public void myHandle(TestBean tb, HttpServletResponse response) throws IOException { - response.getWriter().write("test-" + tb.getName() + "-" + tb.getAge()); - } - - @RequestMapping("/myPath4.do") - public void myHandle(TestBean tb, Errors errors, HttpServletResponse response) throws IOException { - response.getWriter().write("test-" + tb.getName() + "-" + errors.getFieldError("age").getCode()); - } - } - - - @Controller - @RequestMapping("/*.do") - private static class MyAdaptedController2 { - - @RequestMapping - public void myHandle(HttpServletRequest request, HttpServletResponse response) throws IOException { - response.getWriter().write("test"); - } - - @RequestMapping("/myPath2.do") - public void myHandle(@RequestParam("param1") String p1, int param2, HttpServletResponse response) throws IOException { - response.getWriter().write("test-" + p1 + "-" + param2); - } - - @RequestMapping("/myPath3") - public void myHandle(TestBean tb, HttpServletResponse response) throws IOException { - response.getWriter().write("test-" + tb.getName() + "-" + tb.getAge()); - } - - @RequestMapping("/myPath4.*") - public void myHandle(TestBean tb, Errors errors, HttpServletResponse response) throws IOException { - response.getWriter().write("test-" + tb.getName() + "-" + errors.getFieldError("age").getCode()); - } - } - - - @Controller - private static class MyAdaptedControllerBase { - - @RequestMapping("/myPath2.do") - public void myHandle(@RequestParam("param1") T p1, int param2, HttpServletResponse response) throws IOException { - response.getWriter().write("test-" + p1 + "-" + param2); - } - - @InitBinder - public void initBinder(@RequestParam("param1") T p1, int param2) { - } - - @ModelAttribute - public void modelAttribute(@RequestParam("param1") T p1, int param2) { - } - } - - - @RequestMapping("/*.do") - private static class MyAdaptedController3 extends MyAdaptedControllerBase { - - @RequestMapping - public void myHandle(HttpServletRequest request, HttpServletResponse response) throws IOException { - response.getWriter().write("test"); - } - - @Override - public void myHandle(@RequestParam("param1") String p1, int param2, HttpServletResponse response) throws IOException { - response.getWriter().write("test-" + p1 + "-" + param2); - } - - @RequestMapping("/myPath3") - public void myHandle(TestBean tb, HttpServletResponse response) throws IOException { - response.getWriter().write("test-" + tb.getName() + "-" + tb.getAge()); - } - - @RequestMapping("/myPath4.*") - public void myHandle(TestBean tb, Errors errors, HttpServletResponse response) throws IOException { - response.getWriter().write("test-" + tb.getName() + "-" + errors.getFieldError("age").getCode()); - } - - @InitBinder - public void initBinder(@RequestParam("param1") String p1, int param2) { - } - - @ModelAttribute - public void modelAttribute(@RequestParam("param1") String p1, int param2) { - } - } - - - @Controller - @RequestMapping(method = RequestMethod.GET) - private static class EmptyParameterListHandlerMethodController { - - static boolean called; - - @RequestMapping("/emptyParameterListHandler") - public void emptyParameterListHandler() { - EmptyParameterListHandlerMethodController.called = true; - } - - @RequestMapping("/nonEmptyParameterListHandler") - public void nonEmptyParameterListHandler(HttpServletResponse response) { - } - } - - - @Controller - public static class MyFormController { - - @ModelAttribute("testBeanList") - public List getTestBeans() { - List list = new LinkedList(); - list.add(new TestBean("tb1")); - list.add(new TestBean("tb2")); - return list; - } - - @RequestMapping("/myPath.do") - public String myHandle(@ModelAttribute("myCommand") TestBean tb, BindingResult errors, ModelMap model) { - if (!model.containsKey("myKey")) { - model.addAttribute("myKey", "myValue"); - } - return "myView"; - } - } - - - @Controller - public static class MyModelFormController { - - @ModelAttribute - public List getTestBeans() { - List list = new LinkedList(); - list.add(new TestBean("tb1")); - list.add(new TestBean("tb2")); - return list; - } - - @RequestMapping("/myPath.do") - public String myHandle(@ModelAttribute("myCommand") TestBean tb, BindingResult errors, Model model) { - if (!model.containsAttribute("myKey")) { - model.addAttribute("myKey", "myValue"); - } - return "myView"; - } - } - - - @Controller - private static class MyCommandProvidingFormController extends MyFormController { - - @SuppressWarnings("unused") - @ModelAttribute("myCommand") - private TestBean createTestBean( - @RequestParam T defaultName, Map model, @RequestParam Date date) { - model.put("myKey", "myOriginalValue"); - return new TestBean(defaultName.getClass().getSimpleName() + ":" + defaultName.toString()); - } - - @RequestMapping("/myPath.do") - public String myHandle(@ModelAttribute("myCommand") TestBean tb, BindingResult errors, ModelMap model) { - return super.myHandle(tb, errors, model); - } - - @RequestMapping("/myOtherPath.do") - public String myOtherHandle(TB tb, BindingResult errors, ExtendedModelMap model, MySpecialArg arg) { - TestBean tbReal = (TestBean) tb; - tbReal.setName("myName"); - assertTrue(model.get("ITestBean") instanceof DerivedTestBean); - assertNotNull(arg); - return super.myHandle(tbReal, errors, model); - } - - @RequestMapping("/myThirdPath.do") - public String myThirdHandle(TB tb, Model model) { - model.addAttribute("testBean", new TestBean("special", 99)); - return "myView"; - } - - @ModelAttribute - protected TB2 getModelAttr() { - return (TB2) new DerivedTestBean(); - } - } - - - private static class MySpecialArg { - - public MySpecialArg(String value) { - } - } - - - @Controller - private static class MyTypedCommandProvidingFormController - extends MyCommandProvidingFormController { - } - - - @Controller - private static class MyBinderInitializingCommandProvidingFormController extends MyCommandProvidingFormController { - - @SuppressWarnings("unused") - @InitBinder - private void initBinder(WebDataBinder binder) { - binder.initBeanPropertyAccess(); - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); - dateFormat.setLenient(false); - binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false)); - } - } - - - @Controller - private static class MySpecificBinderInitializingCommandProvidingFormController extends MyCommandProvidingFormController { - - @SuppressWarnings("unused") - @InitBinder({"myCommand", "date"}) - private void initBinder(WebDataBinder binder, String date, @RequestParam("date") String[] date2) { - assertEquals("2007-10-02", date); - assertEquals(1, date2.length); - assertEquals("2007-10-02", date2[0]); - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); - dateFormat.setLenient(false); - binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false)); - } - } - - - private static class MyWebBindingInitializer implements WebBindingInitializer { - - public void initBinder(WebDataBinder binder, WebRequest request) { - assertNotNull(request.getLocale()); - SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); - dateFormat.setLenient(false); - binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false)); - } - } - - - private static class MySpecialArgumentResolver implements WebArgumentResolver { - - public Object resolveArgument(MethodParameter methodParameter, NativeWebRequest webRequest) { - if (methodParameter.getParameterType().equals(MySpecialArg.class)) { - return new MySpecialArg("myValue"); - } - return UNRESOLVED; - } - } - - - @Controller - @RequestMapping("/myPath.do") - private static class MyParameterDispatchingController { - - @Autowired - private ServletContext servletContext; - - @Autowired - private ServletConfig servletConfig; - - @Autowired - private HttpSession session; - - @Autowired - private HttpServletRequest request; - - @RequestMapping - public void myHandle(HttpServletResponse response, HttpServletRequest request) throws IOException { - if (this.servletContext == null || this.servletConfig == null || this.session == null || this.request == null) { - throw new IllegalStateException(); - } - response.getWriter().write("myView"); - request.setAttribute("servletContext", this.servletContext); - request.setAttribute("servletConfig", this.servletConfig); - request.setAttribute("session", this.session); - request.setAttribute("request", this.request); - } - - @RequestMapping(params = {"view", "!lang"}) - public void myOtherHandle(HttpServletResponse response) throws IOException { - response.getWriter().write("myOtherView"); - } - - @RequestMapping(method = RequestMethod.GET, params = {"view=my", "lang=de"}) - public void myLangHandle(HttpServletResponse response) throws IOException { - response.getWriter().write("myLangView"); - } - - @RequestMapping(method = {RequestMethod.POST, RequestMethod.GET}, params = "surprise") - public void mySurpriseHandle(HttpServletResponse response) throws IOException { - response.getWriter().write("mySurpriseView"); - } - } - - - @Controller - @RequestMapping(value = "/*.do", method = RequestMethod.POST, params = "myParam=myValue") - private static class MyPostMethodNameDispatchingController extends MethodNameDispatchingController { - - } - - - @Controller - @RequestMapping("/myApp/*") - private static class MyRelativePathDispatchingController { - - @RequestMapping - public void myHandle(HttpServletResponse response) throws IOException { - response.getWriter().write("myView"); - } - - @RequestMapping("*Other") - public void myOtherHandle(HttpServletResponse response) throws IOException { - response.getWriter().write("myOtherView"); - } - - @RequestMapping("myLang") - public void myLangHandle(HttpServletResponse response) throws IOException { - response.getWriter().write("myLangView"); - } - - @RequestMapping("surprise") - public void mySurpriseHandle(HttpServletResponse response) throws IOException { - response.getWriter().write("mySurpriseView"); - } - } - - - @Controller - private static class MyNullCommandController { - - @ModelAttribute - public TestBean getTestBean() { - return null; - } - - @ModelAttribute - public Principal getPrincipal() { - return new TestPrincipal(); - } - - @RequestMapping("/myPath") - public void handle(@ModelAttribute TestBean testBean, Errors errors, - @ModelAttribute TestPrincipal modelPrinc, OtherPrincipal requestPrinc, Writer writer) throws IOException { - assertNull(testBean); - assertNotNull(modelPrinc); - assertNotNull(requestPrinc); - assertFalse(errors.hasErrors()); - errors.reject("myCode"); - writer.write("myView"); - } - } - - - private static class TestPrincipal implements Principal { - - public String getName() { - return "test"; - } - } - - - private static class OtherPrincipal implements Principal { - - public String getName() { - return "other"; - } - } - - - private static class TestViewResolver implements ViewResolver { - - public View resolveViewName(final String viewName, Locale locale) throws Exception { - return new View() { - public String getContentType() { - return null; - } - @SuppressWarnings({"unchecked", "deprecation"}) - public void render(Map model, HttpServletRequest request, HttpServletResponse response) throws Exception { - TestBean tb = (TestBean) model.get("testBean"); - if (tb == null) { - tb = (TestBean) model.get("myCommand"); - } - if (tb.getName().endsWith("myDefaultName")) { - assertTrue(tb.getDate().getYear() == 107); - } - Errors errors = (Errors) model.get(BindingResult.MODEL_KEY_PREFIX + "testBean"); - if (errors == null) { - errors = (Errors) model.get(BindingResult.MODEL_KEY_PREFIX + "myCommand"); - } - if (errors.hasFieldErrors("date")) { - throw new IllegalStateException(); - } - if (model.containsKey("ITestBean")) { - assertTrue(model.get(BindingResult.MODEL_KEY_PREFIX + "ITestBean") instanceof Errors); - } - List testBeans = (List) model.get("testBeanList"); - if (errors.hasFieldErrors("age")) { - response.getWriter().write(viewName + "-" + tb.getName() + "-" + errors.getFieldError("age").getCode() + - "-" + testBeans.get(0).getName() + "-" + model.get("myKey")); - } - else { - response.getWriter().write(viewName + "-" + tb.getName() + "-" + tb.getAge() + "-" + - errors.getFieldValue("name") + "-" + errors.getFieldValue("age")); - } - } - }; - } - } - - - public static class ParentController { - - @RequestMapping(method = RequestMethod.GET) - public void doGet(HttpServletRequest req, HttpServletResponse resp) { - } - } - - - @Controller - @RequestMapping("/child/test") - public static class ChildController extends ParentController { - - @RequestMapping(method = RequestMethod.GET) - public void doGet(HttpServletRequest req, HttpServletResponse resp, @RequestParam("childId") String id) { - } - } - -} diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/DelegatingServletInputStream.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/DelegatingServletInputStream.java new file mode 100644 index 0000000000..6b9ec44af2 --- /dev/null +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/DelegatingServletInputStream.java @@ -0,0 +1,67 @@ +/* + * Copyright 2002-2007 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.mock.web; + +import java.io.IOException; +import java.io.InputStream; + +import javax.servlet.ServletInputStream; + +import org.springframework.util.Assert; + +/** + * Delegating implementation of {@link javax.servlet.ServletInputStream}. + * + *

Used by {@link org.springframework.mock.web.MockHttpServletRequest}; typically not directly + * used for testing application controllers. + * + * @author Juergen Hoeller + * @since 1.0.2 + * @see org.springframework.mock.web.MockHttpServletRequest + */ +public class DelegatingServletInputStream extends ServletInputStream { + + private final InputStream sourceStream; + + + /** + * Create a DelegatingServletInputStream for the given source stream. + * @param sourceStream the source stream (never null) + */ + public DelegatingServletInputStream(InputStream sourceStream) { + Assert.notNull(sourceStream, "Source InputStream must not be null"); + this.sourceStream = sourceStream; + } + + /** + * Return the underlying source stream (never null). + */ + public final InputStream getSourceStream() { + return this.sourceStream; + } + + + public int read() throws IOException { + return this.sourceStream.read(); + } + + public void close() throws IOException { + super.close(); + this.sourceStream.close(); + } + +} \ No newline at end of file diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/DelegatingServletOutputStream.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/DelegatingServletOutputStream.java new file mode 100644 index 0000000000..84eec6c70c --- /dev/null +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/DelegatingServletOutputStream.java @@ -0,0 +1,72 @@ +/* + * Copyright 2002-2007 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.mock.web; + +import java.io.IOException; +import java.io.OutputStream; + +import javax.servlet.ServletOutputStream; + +import org.springframework.util.Assert; + +/** + * Delegating implementation of {@link javax.servlet.ServletOutputStream}. + * + *

Used by {@link org.springframework.mock.web.MockHttpServletResponse}; typically not directly + * used for testing application controllers. + * + * @author Juergen Hoeller + * @since 1.0.2 + * @see org.springframework.mock.web.MockHttpServletResponse + */ +public class DelegatingServletOutputStream extends ServletOutputStream { + + private final OutputStream targetStream; + + + /** + * Create a DelegatingServletOutputStream for the given target stream. + * @param targetStream the target stream (never null) + */ + public DelegatingServletOutputStream(OutputStream targetStream) { + Assert.notNull(targetStream, "Target OutputStream must not be null"); + this.targetStream = targetStream; + } + + /** + * Return the underlying target stream (never null). + */ + public final OutputStream getTargetStream() { + return this.targetStream; + } + + + public void write(int b) throws IOException { + this.targetStream.write(b); + } + + public void flush() throws IOException { + super.flush(); + this.targetStream.flush(); + } + + public void close() throws IOException { + super.close(); + this.targetStream.close(); + } + +} \ No newline at end of file diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/HeaderValueHolder.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/HeaderValueHolder.java new file mode 100644 index 0000000000..97da5e9d43 --- /dev/null +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/HeaderValueHolder.java @@ -0,0 +1,85 @@ +/* + * Copyright 2002-2007 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.mock.web; + +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; + +/** + * Internal helper class that serves as value holder for request headers. + * + * @author Juergen Hoeller + * @author Rick Evans + * @since 2.0.1 + */ +class HeaderValueHolder { + + private final List values = new LinkedList(); + + + public void setValue(Object value) { + this.values.clear(); + this.values.add(value); + } + + public void addValue(Object value) { + this.values.add(value); + } + + public void addValues(Collection values) { + this.values.addAll(values); + } + + public void addValueArray(Object values) { + CollectionUtils.mergeArrayIntoCollection(values, this.values); + } + + public List getValues() { + return Collections.unmodifiableList(this.values); + } + + public Object getValue() { + return (!this.values.isEmpty() ? this.values.get(0) : null); + } + + + /** + * Find a HeaderValueHolder by name, ignoring casing. + * @param headers the Map of header names to HeaderValueHolders + * @param name the name of the desired header + * @return the corresponding HeaderValueHolder, + * or null if none found + */ + public static HeaderValueHolder getByName(Map headers, String name) { + Assert.notNull(name, "Header name must not be null"); + for (Iterator it = headers.keySet().iterator(); it.hasNext();) { + String headerName = (String) it.next(); + if (headerName.equalsIgnoreCase(name)) { + return (HeaderValueHolder) headers.get(headerName); + } + } + return null; + } + +} \ No newline at end of file diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockHttpServletRequest.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockHttpServletRequest.java new file mode 100644 index 0000000000..93976202b2 --- /dev/null +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockHttpServletRequest.java @@ -0,0 +1,858 @@ +/* + * Copyright 2002-2008 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.mock.web; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.UnsupportedEncodingException; +import java.security.Principal; +import java.util.Collection; +import java.util.Collections; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.Vector; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletContext; +import javax.servlet.ServletInputStream; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.springframework.util.Assert; + +/** + * Mock implementation of the {@link javax.servlet.http.HttpServletRequest} + * interface. Supports the Servlet 2.4 API level. + * + *

Used for testing the web framework; also useful for testing + * application controllers. + * + * @author Juergen Hoeller + * @author Rod Johnson + * @author Rick Evans + * @author Mark Fisher + * @since 1.0.2 + */ +public class MockHttpServletRequest implements HttpServletRequest { + + /** + * The default protocol: 'http'. + */ + public static final String DEFAULT_PROTOCOL = "http"; + + /** + * The default server address: '127.0.0.1'. + */ + public static final String DEFAULT_SERVER_ADDR = "127.0.0.1"; + + /** + * The default server name: 'localhost'. + */ + public static final String DEFAULT_SERVER_NAME = "localhost"; + + /** + * The default server port: '80'. + */ + public static final int DEFAULT_SERVER_PORT = 80; + + /** + * The default remote address: '127.0.0.1'. + */ + public static final String DEFAULT_REMOTE_ADDR = "127.0.0.1"; + + /** + * The default remote host: 'localhost'. + */ + public static final String DEFAULT_REMOTE_HOST = "localhost"; + + + private boolean active = true; + + + //--------------------------------------------------------------------- + // ServletRequest properties + //--------------------------------------------------------------------- + + private final Hashtable attributes = new Hashtable(); + + private String characterEncoding; + + private byte[] content; + + private String contentType; + + private final Map parameters = new LinkedHashMap(16); + + private String protocol = DEFAULT_PROTOCOL; + + private String scheme = DEFAULT_PROTOCOL; + + private String serverName = DEFAULT_SERVER_NAME; + + private int serverPort = DEFAULT_SERVER_PORT; + + private String remoteAddr = DEFAULT_REMOTE_ADDR; + + private String remoteHost = DEFAULT_REMOTE_HOST; + + /** List of locales in descending order */ + private final Vector locales = new Vector(); + + private boolean secure = false; + + private final ServletContext servletContext; + + private int remotePort = DEFAULT_SERVER_PORT; + + private String localName = DEFAULT_SERVER_NAME; + + private String localAddr = DEFAULT_SERVER_ADDR; + + private int localPort = DEFAULT_SERVER_PORT; + + + //--------------------------------------------------------------------- + // HttpServletRequest properties + //--------------------------------------------------------------------- + + private String authType; + + private Cookie[] cookies; + + /** + * The key is the lowercase header name; the value is a {@link org.springframework.mock.web.HeaderValueHolder} object. + */ + private final Hashtable headers = new Hashtable(); + + private String method; + + private String pathInfo; + + private String contextPath = ""; + + private String queryString; + + private String remoteUser; + + private final Set userRoles = new HashSet(); + + private Principal userPrincipal; + + private String requestURI; + + private String servletPath = ""; + + private HttpSession session; + + private boolean requestedSessionIdValid = true; + + private boolean requestedSessionIdFromCookie = true; + + private boolean requestedSessionIdFromURL = false; + + + //--------------------------------------------------------------------- + // Constructors + //--------------------------------------------------------------------- + + /** + * Create a new MockHttpServletRequest with a default + * {@link org.springframework.mock.web.MockServletContext}. + * @see org.springframework.mock.web.MockServletContext + */ + public MockHttpServletRequest() { + this(null, "", ""); + } + + /** + * Create a new MockHttpServletRequest with a default + * {@link org.springframework.mock.web.MockServletContext}. + * @param method the request method (may be null) + * @param requestURI the request URI (may be null) + * @see #setMethod + * @see #setRequestURI + * @see org.springframework.mock.web.MockServletContext + */ + public MockHttpServletRequest(String method, String requestURI) { + this(null, method, requestURI); + } + + /** + * Create a new MockHttpServletRequest. + * @param servletContext the ServletContext that the request runs in + * (may be null to use a default MockServletContext) + * @see org.springframework.mock.web.MockServletContext + */ + public MockHttpServletRequest(ServletContext servletContext) { + this(servletContext, "", ""); + } + + /** + * Create a new MockHttpServletRequest. + * @param servletContext the ServletContext that the request runs in + * (may be null to use a default MockServletContext) + * @param method the request method (may be null) + * @param requestURI the request URI (may be null) + * @see #setMethod + * @see #setRequestURI + * @see org.springframework.mock.web.MockServletContext + */ + public MockHttpServletRequest(ServletContext servletContext, String method, String requestURI) { + this.servletContext = (servletContext != null ? servletContext : new MockServletContext()); + this.method = method; + this.requestURI = requestURI; + this.locales.add(Locale.ENGLISH); + } + + + //--------------------------------------------------------------------- + // Lifecycle methods + //--------------------------------------------------------------------- + + /** + * Return the ServletContext that this request is associated with. + * (Not available in the standard HttpServletRequest interface for some reason.) + */ + public ServletContext getServletContext() { + return this.servletContext; + } + + /** + * Return whether this request is still active (that is, not completed yet). + */ + public boolean isActive() { + return this.active; + } + + /** + * Mark this request as completed, keeping its state. + */ + public void close() { + this.active = false; + } + + /** + * Invalidate this request, clearing its state. + */ + public void invalidate() { + close(); + clearAttributes(); + } + + /** + * Check whether this request is still active (that is, not completed yet), + * throwing an IllegalStateException if not active anymore. + */ + protected void checkActive() throws IllegalStateException { + if (!this.active) { + throw new IllegalStateException("Request is not active anymore"); + } + } + + + //--------------------------------------------------------------------- + // ServletRequest interface + //--------------------------------------------------------------------- + + public Object getAttribute(String name) { + checkActive(); + return this.attributes.get(name); + } + + public Enumeration getAttributeNames() { + checkActive(); + return this.attributes.keys(); + } + + public String getCharacterEncoding() { + return this.characterEncoding; + } + + public void setCharacterEncoding(String characterEncoding) { + this.characterEncoding = characterEncoding; + } + + public void setContent(byte[] content) { + this.content = content; + } + + public int getContentLength() { + return (this.content != null ? this.content.length : -1); + } + + public void setContentType(String contentType) { + this.contentType = contentType; + } + + public String getContentType() { + return this.contentType; + } + + public ServletInputStream getInputStream() { + if (this.content != null) { + return new DelegatingServletInputStream(new ByteArrayInputStream(this.content)); + } + else { + return null; + } + } + + /** + * Set a single value for the specified HTTP parameter. + *

If there are already one or more values registered for the given + * parameter name, they will be replaced. + */ + public void setParameter(String name, String value) { + setParameter(name, new String[] {value}); + } + + /** + * Set an array of values for the specified HTTP parameter. + *

If there are already one or more values registered for the given + * parameter name, they will be replaced. + */ + public void setParameter(String name, String[] values) { + Assert.notNull(name, "Parameter name must not be null"); + this.parameters.put(name, values); + } + + /** + * Sets all provided parameters replacing any + * existing values for the provided parameter names. To add without + * replacing existing values, use {@link #addParameters(java.util.Map)}. + */ + public void setParameters(Map params) { + Assert.notNull(params, "Parameter map must not be null"); + for (Iterator it = params.keySet().iterator(); it.hasNext();) { + Object key = it.next(); + Assert.isInstanceOf(String.class, key, + "Parameter map key must be of type [" + String.class.getName() + "]"); + Object value = params.get(key); + if (value instanceof String) { + this.setParameter((String) key, (String) value); + } + else if (value instanceof String[]) { + this.setParameter((String) key, (String[]) value); + } + else { + throw new IllegalArgumentException("Parameter map value must be single value " + + " or array of type [" + String.class.getName() + "]"); + } + } + } + + /** + * Add a single value for the specified HTTP parameter. + *

If there are already one or more values registered for the given + * parameter name, the given value will be added to the end of the list. + */ + public void addParameter(String name, String value) { + addParameter(name, new String[] {value}); + } + + /** + * Add an array of values for the specified HTTP parameter. + *

If there are already one or more values registered for the given + * parameter name, the given values will be added to the end of the list. + */ + public void addParameter(String name, String[] values) { + Assert.notNull(name, "Parameter name must not be null"); + String[] oldArr = (String[]) this.parameters.get(name); + if (oldArr != null) { + String[] newArr = new String[oldArr.length + values.length]; + System.arraycopy(oldArr, 0, newArr, 0, oldArr.length); + System.arraycopy(values, 0, newArr, oldArr.length, values.length); + this.parameters.put(name, newArr); + } + else { + this.parameters.put(name, values); + } + } + + /** + * Adds all provided parameters without replacing + * any existing values. To replace existing values, use + * {@link #setParameters(java.util.Map)}. + */ + public void addParameters(Map params) { + Assert.notNull(params, "Parameter map must not be null"); + for (Iterator it = params.keySet().iterator(); it.hasNext();) { + Object key = it.next(); + Assert.isInstanceOf(String.class, key, + "Parameter map key must be of type [" + String.class.getName() + "]"); + Object value = params.get(key); + if (value instanceof String) { + this.addParameter((String) key, (String) value); + } + else if (value instanceof String[]) { + this.addParameter((String) key, (String[]) value); + } + else { + throw new IllegalArgumentException("Parameter map value must be single value " + + " or array of type [" + String.class.getName() + "]"); + } + } + } + + /** + * Remove already registered values for the specified HTTP parameter, if any. + */ + public void removeParameter(String name) { + Assert.notNull(name, "Parameter name must not be null"); + this.parameters.remove(name); + } + + /** + * Removes all existing parameters. + */ + public void removeAllParameters() { + this.parameters.clear(); + } + + public String getParameter(String name) { + Assert.notNull(name, "Parameter name must not be null"); + String[] arr = (String[]) this.parameters.get(name); + return (arr != null && arr.length > 0 ? arr[0] : null); + } + + public Enumeration getParameterNames() { + return Collections.enumeration(this.parameters.keySet()); + } + + public String[] getParameterValues(String name) { + Assert.notNull(name, "Parameter name must not be null"); + return (String[]) this.parameters.get(name); + } + + public Map getParameterMap() { + return Collections.unmodifiableMap(this.parameters); + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public String getProtocol() { + return this.protocol; + } + + public void setScheme(String scheme) { + this.scheme = scheme; + } + + public String getScheme() { + return this.scheme; + } + + public void setServerName(String serverName) { + this.serverName = serverName; + } + + public String getServerName() { + return this.serverName; + } + + public void setServerPort(int serverPort) { + this.serverPort = serverPort; + } + + public int getServerPort() { + return this.serverPort; + } + + public BufferedReader getReader() throws UnsupportedEncodingException { + if (this.content != null) { + InputStream sourceStream = new ByteArrayInputStream(this.content); + Reader sourceReader = (this.characterEncoding != null) ? + new InputStreamReader(sourceStream, this.characterEncoding) : new InputStreamReader(sourceStream); + return new BufferedReader(sourceReader); + } + else { + return null; + } + } + + public void setRemoteAddr(String remoteAddr) { + this.remoteAddr = remoteAddr; + } + + public String getRemoteAddr() { + return this.remoteAddr; + } + + public void setRemoteHost(String remoteHost) { + this.remoteHost = remoteHost; + } + + public String getRemoteHost() { + return this.remoteHost; + } + + public void setAttribute(String name, Object value) { + checkActive(); + Assert.notNull(name, "Attribute name must not be null"); + if (value != null) { + this.attributes.put(name, value); + } + else { + this.attributes.remove(name); + } + } + + public void removeAttribute(String name) { + checkActive(); + Assert.notNull(name, "Attribute name must not be null"); + this.attributes.remove(name); + } + + /** + * Clear all of this request's attributes. + */ + public void clearAttributes() { + this.attributes.clear(); + } + + /** + * Add a new preferred locale, before any existing locales. + */ + public void addPreferredLocale(Locale locale) { + Assert.notNull(locale, "Locale must not be null"); + this.locales.add(0, locale); + } + + public Locale getLocale() { + return (Locale) this.locales.get(0); + } + + public Enumeration getLocales() { + return this.locales.elements(); + } + + public void setSecure(boolean secure) { + this.secure = secure; + } + + public boolean isSecure() { + return this.secure; + } + + public RequestDispatcher getRequestDispatcher(String path) { + return new MockRequestDispatcher(path); + } + + public String getRealPath(String path) { + return this.servletContext.getRealPath(path); + } + + public void setRemotePort(int remotePort) { + this.remotePort = remotePort; + } + + public int getRemotePort() { + return this.remotePort; + } + + public void setLocalName(String localName) { + this.localName = localName; + } + + public String getLocalName() { + return this.localName; + } + + public void setLocalAddr(String localAddr) { + this.localAddr = localAddr; + } + + public String getLocalAddr() { + return this.localAddr; + } + + public void setLocalPort(int localPort) { + this.localPort = localPort; + } + + public int getLocalPort() { + return this.localPort; + } + + + //--------------------------------------------------------------------- + // HttpServletRequest interface + //--------------------------------------------------------------------- + + public void setAuthType(String authType) { + this.authType = authType; + } + + public String getAuthType() { + return this.authType; + } + + public void setCookies(Cookie[] cookies) { + this.cookies = cookies; + } + + public Cookie[] getCookies() { + return this.cookies; + } + + /** + * Add a header entry for the given name. + *

If there was no entry for that header name before, + * the value will be used as-is. In case of an existing entry, + * a String array will be created, adding the given value (more + * specifically, its toString representation) as further element. + *

Multiple values can only be stored as list of Strings, + * following the Servlet spec (see getHeaders accessor). + * As alternative to repeated addHeader calls for + * individual elements, you can use a single call with an entire + * array or Collection of values as parameter. + * @see #getHeaderNames + * @see #getHeader + * @see #getHeaders + * @see #getDateHeader + * @see #getIntHeader + */ + public void addHeader(String name, Object value) { + HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); + Assert.notNull(value, "Header value must not be null"); + if (header == null) { + header = new HeaderValueHolder(); + this.headers.put(name, header); + } + if (value instanceof Collection) { + header.addValues((Collection) value); + } + else if (value.getClass().isArray()) { + header.addValueArray(value); + } + else { + header.addValue(value); + } + } + + public long getDateHeader(String name) { + HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); + Object value = (header != null ? header.getValue() : null); + if (value instanceof Date) { + return ((Date) value).getTime(); + } + else if (value instanceof Number) { + return ((Number) value).longValue(); + } + else if (value != null) { + throw new IllegalArgumentException( + "Value for header '" + name + "' is neither a Date nor a Number: " + value); + } + else { + return -1L; + } + } + + public String getHeader(String name) { + HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); + return (header != null ? header.getValue().toString() : null); + } + + public Enumeration getHeaders(String name) { + HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); + return Collections.enumeration(header != null ? header.getValues() : Collections.EMPTY_LIST); + } + + public Enumeration getHeaderNames() { + return this.headers.keys(); + } + + public int getIntHeader(String name) { + HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); + Object value = (header != null ? header.getValue() : null); + if (value instanceof Number) { + return ((Number) value).intValue(); + } + else if (value instanceof String) { + return Integer.parseInt((String) value); + } + else if (value != null) { + throw new NumberFormatException("Value for header '" + name + "' is not a Number: " + value); + } + else { + return -1; + } + } + + public void setMethod(String method) { + this.method = method; + } + + public String getMethod() { + return this.method; + } + + public void setPathInfo(String pathInfo) { + this.pathInfo = pathInfo; + } + + public String getPathInfo() { + return this.pathInfo; + } + + public String getPathTranslated() { + return (this.pathInfo != null ? getRealPath(this.pathInfo) : null); + } + + public void setContextPath(String contextPath) { + this.contextPath = contextPath; + } + + public String getContextPath() { + return this.contextPath; + } + + public void setQueryString(String queryString) { + this.queryString = queryString; + } + + public String getQueryString() { + return this.queryString; + } + + public void setRemoteUser(String remoteUser) { + this.remoteUser = remoteUser; + } + + public String getRemoteUser() { + return this.remoteUser; + } + + /** + * @deprecated in favor of addUserRole + * @see #addUserRole + */ + public void addRole(String role) { + addUserRole(role); + } + + public void addUserRole(String role) { + this.userRoles.add(role); + } + + public boolean isUserInRole(String role) { + return this.userRoles.contains(role); + } + + public void setUserPrincipal(Principal userPrincipal) { + this.userPrincipal = userPrincipal; + } + + public Principal getUserPrincipal() { + return this.userPrincipal; + } + + public String getRequestedSessionId() { + HttpSession session = getSession(); + return (session != null ? session.getId() : null); + } + + public void setRequestURI(String requestURI) { + this.requestURI = requestURI; + } + + public String getRequestURI() { + return this.requestURI; + } + + public StringBuffer getRequestURL() { + StringBuffer url = new StringBuffer(this.scheme); + url.append("://").append(this.serverName).append(':').append(this.serverPort); + url.append(getRequestURI()); + return url; + } + + public void setServletPath(String servletPath) { + this.servletPath = servletPath; + } + + public String getServletPath() { + return this.servletPath; + } + + public void setSession(HttpSession session) { + this.session = session; + if (session instanceof MockHttpSession) { + MockHttpSession mockSession = ((MockHttpSession) session); + mockSession.access(); + } + } + + public HttpSession getSession(boolean create) { + checkActive(); + // Reset session if invalidated. + if (this.session instanceof MockHttpSession && ((MockHttpSession) this.session).isInvalid()) { + this.session = null; + } + // Create new session if necessary. + if (this.session == null && create) { + this.session = new MockHttpSession(this.servletContext); + } + return this.session; + } + + public HttpSession getSession() { + return getSession(true); + } + + public void setRequestedSessionIdValid(boolean requestedSessionIdValid) { + this.requestedSessionIdValid = requestedSessionIdValid; + } + + public boolean isRequestedSessionIdValid() { + return this.requestedSessionIdValid; + } + + public void setRequestedSessionIdFromCookie(boolean requestedSessionIdFromCookie) { + this.requestedSessionIdFromCookie = requestedSessionIdFromCookie; + } + + public boolean isRequestedSessionIdFromCookie() { + return this.requestedSessionIdFromCookie; + } + + public void setRequestedSessionIdFromURL(boolean requestedSessionIdFromURL) { + this.requestedSessionIdFromURL = requestedSessionIdFromURL; + } + + public boolean isRequestedSessionIdFromURL() { + return this.requestedSessionIdFromURL; + } + + public boolean isRequestedSessionIdFromUrl() { + return isRequestedSessionIdFromURL(); + } + +} \ No newline at end of file diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockHttpServletResponse.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockHttpServletResponse.java new file mode 100644 index 0000000000..cb848d8512 --- /dev/null +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockHttpServletResponse.java @@ -0,0 +1,517 @@ +/* + * Copyright 2002-2008 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.mock.web; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.util.Assert; +import org.springframework.web.util.WebUtils; + +/** + * Mock implementation of the {@link javax.servlet.http.HttpServletResponse} + * interface. Supports the Servlet 2.4 API level. + * + *

Used for testing the web framework; also useful for testing + * application controllers. + * + * @author Juergen Hoeller + * @author Rod Johnson + * @since 1.0.2 + */ +public class MockHttpServletResponse implements HttpServletResponse { + + public static final int DEFAULT_SERVER_PORT = 80; + + private static final String CHARSET_PREFIX = "charset="; + + + //--------------------------------------------------------------------- + // ServletResponse properties + //--------------------------------------------------------------------- + + private boolean outputStreamAccessAllowed = true; + + private boolean writerAccessAllowed = true; + + private String characterEncoding = WebUtils.DEFAULT_CHARACTER_ENCODING; + + private final ByteArrayOutputStream content = new ByteArrayOutputStream(); + + private final ServletOutputStream outputStream = new ResponseServletOutputStream(this.content); + + private PrintWriter writer; + + private int contentLength = 0; + + private String contentType; + + private int bufferSize = 4096; + + private boolean committed; + + private Locale locale = Locale.getDefault(); + + + //--------------------------------------------------------------------- + // HttpServletResponse properties + //--------------------------------------------------------------------- + + private final List cookies = new ArrayList(); + + /** + * The key is the lowercase header name; the value is a {@link org.springframework.mock.web.HeaderValueHolder} object. + */ + private final Map headers = new HashMap(); + + private int status = HttpServletResponse.SC_OK; + + private String errorMessage; + + private String redirectedUrl; + + private String forwardedUrl; + + private String includedUrl; + + + //--------------------------------------------------------------------- + // ServletResponse interface + //--------------------------------------------------------------------- + + /** + * Set whether {@link #getOutputStream()} access is allowed. + *

Default is true. + */ + public void setOutputStreamAccessAllowed(boolean outputStreamAccessAllowed) { + this.outputStreamAccessAllowed = outputStreamAccessAllowed; + } + + /** + * Return whether {@link #getOutputStream()} access is allowed. + */ + public boolean isOutputStreamAccessAllowed() { + return this.outputStreamAccessAllowed; + } + + /** + * Set whether {@link #getWriter()} access is allowed. + *

Default is true. + */ + public void setWriterAccessAllowed(boolean writerAccessAllowed) { + this.writerAccessAllowed = writerAccessAllowed; + } + + /** + * Return whether {@link #getOutputStream()} access is allowed. + */ + public boolean isWriterAccessAllowed() { + return this.writerAccessAllowed; + } + + public void setCharacterEncoding(String characterEncoding) { + this.characterEncoding = characterEncoding; + } + + public String getCharacterEncoding() { + return this.characterEncoding; + } + + public ServletOutputStream getOutputStream() { + if (!this.outputStreamAccessAllowed) { + throw new IllegalStateException("OutputStream access not allowed"); + } + return this.outputStream; + } + + public PrintWriter getWriter() throws UnsupportedEncodingException { + if (!this.writerAccessAllowed) { + throw new IllegalStateException("Writer access not allowed"); + } + if (this.writer == null) { + Writer targetWriter = (this.characterEncoding != null ? + new OutputStreamWriter(this.content, this.characterEncoding) : new OutputStreamWriter(this.content)); + this.writer = new ResponsePrintWriter(targetWriter); + } + return this.writer; + } + + public byte[] getContentAsByteArray() { + flushBuffer(); + return this.content.toByteArray(); + } + + public String getContentAsString() throws UnsupportedEncodingException { + flushBuffer(); + return (this.characterEncoding != null) ? + this.content.toString(this.characterEncoding) : this.content.toString(); + } + + public void setContentLength(int contentLength) { + this.contentLength = contentLength; + } + + public int getContentLength() { + return this.contentLength; + } + + public void setContentType(String contentType) { + this.contentType = contentType; + if (contentType != null) { + int charsetIndex = contentType.toLowerCase().indexOf(CHARSET_PREFIX); + if (charsetIndex != -1) { + String encoding = contentType.substring(charsetIndex + CHARSET_PREFIX.length()); + setCharacterEncoding(encoding); + } + } + } + + public String getContentType() { + return this.contentType; + } + + public void setBufferSize(int bufferSize) { + this.bufferSize = bufferSize; + } + + public int getBufferSize() { + return this.bufferSize; + } + + public void flushBuffer() { + setCommitted(true); + } + + public void resetBuffer() { + if (isCommitted()) { + throw new IllegalStateException("Cannot reset buffer - response is already committed"); + } + this.content.reset(); + } + + private void setCommittedIfBufferSizeExceeded() { + int bufSize = getBufferSize(); + if (bufSize > 0 && this.content.size() > bufSize) { + setCommitted(true); + } + } + + public void setCommitted(boolean committed) { + this.committed = committed; + } + + public boolean isCommitted() { + return this.committed; + } + + public void reset() { + resetBuffer(); + this.characterEncoding = null; + this.contentLength = 0; + this.contentType = null; + this.locale = null; + this.cookies.clear(); + this.headers.clear(); + this.status = HttpServletResponse.SC_OK; + this.errorMessage = null; + } + + public void setLocale(Locale locale) { + this.locale = locale; + } + + public Locale getLocale() { + return this.locale; + } + + + //--------------------------------------------------------------------- + // HttpServletResponse interface + //--------------------------------------------------------------------- + + public void addCookie(Cookie cookie) { + Assert.notNull(cookie, "Cookie must not be null"); + this.cookies.add(cookie); + } + + public Cookie[] getCookies() { + return (Cookie[]) this.cookies.toArray(new Cookie[this.cookies.size()]); + } + + public Cookie getCookie(String name) { + Assert.notNull(name, "Cookie name must not be null"); + for (Iterator it = this.cookies.iterator(); it.hasNext();) { + Cookie cookie = (Cookie) it.next(); + if (name.equals(cookie.getName())) { + return cookie; + } + } + return null; + } + + public boolean containsHeader(String name) { + return (HeaderValueHolder.getByName(this.headers, name) != null); + } + + /** + * Return the names of all specified headers as a Set of Strings. + * @return the Set of header name Strings, or an empty Set if none + */ + public Set getHeaderNames() { + return this.headers.keySet(); + } + + /** + * Return the primary value for the given header, if any. + *

Will return the first value in case of multiple values. + * @param name the name of the header + * @return the associated header value, or null if none + */ + public Object getHeader(String name) { + HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); + return (header != null ? header.getValue() : null); + } + + /** + * Return all values for the given header as a List of value objects. + * @param name the name of the header + * @return the associated header values, or an empty List if none + */ + public List getHeaders(String name) { + HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); + return (header != null ? header.getValues() : Collections.EMPTY_LIST); + } + + /** + * The default implementation returns the given URL String as-is. + *

Can be overridden in subclasses, appending a session id or the like. + */ + public String encodeURL(String url) { + return url; + } + + /** + * The default implementation delegates to {@link #encodeURL}, + * returning the given URL String as-is. + *

Can be overridden in subclasses, appending a session id or the like + * in a redirect-specific fashion. For general URL encoding rules, + * override the common {@link #encodeURL} method instead, appyling + * to redirect URLs as well as to general URLs. + */ + public String encodeRedirectURL(String url) { + return encodeURL(url); + } + + public String encodeUrl(String url) { + return encodeURL(url); + } + + public String encodeRedirectUrl(String url) { + return encodeRedirectURL(url); + } + + public void sendError(int status, String errorMessage) throws IOException { + if (isCommitted()) { + throw new IllegalStateException("Cannot set error status - response is already committed"); + } + this.status = status; + this.errorMessage = errorMessage; + setCommitted(true); + } + + public void sendError(int status) throws IOException { + if (isCommitted()) { + throw new IllegalStateException("Cannot set error status - response is already committed"); + } + this.status = status; + setCommitted(true); + } + + public void sendRedirect(String url) throws IOException { + if (isCommitted()) { + throw new IllegalStateException("Cannot send redirect - response is already committed"); + } + Assert.notNull(url, "Redirect URL must not be null"); + this.redirectedUrl = url; + setCommitted(true); + } + + public String getRedirectedUrl() { + return this.redirectedUrl; + } + + public void setDateHeader(String name, long value) { + setHeaderValue(name, new Long(value)); + } + + public void addDateHeader(String name, long value) { + addHeaderValue(name, new Long(value)); + } + + public void setHeader(String name, String value) { + setHeaderValue(name, value); + } + + public void addHeader(String name, String value) { + addHeaderValue(name, value); + } + + public void setIntHeader(String name, int value) { + setHeaderValue(name, new Integer(value)); + } + + public void addIntHeader(String name, int value) { + addHeaderValue(name, new Integer(value)); + } + + private void setHeaderValue(String name, Object value) { + doAddHeaderValue(name, value, true); + } + + private void addHeaderValue(String name, Object value) { + doAddHeaderValue(name, value, false); + } + + private void doAddHeaderValue(String name, Object value, boolean replace) { + HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name); + Assert.notNull(value, "Header value must not be null"); + if (header == null) { + header = new HeaderValueHolder(); + this.headers.put(name, header); + } + if (replace) { + header.setValue(value); + } + else { + header.addValue(value); + } + } + + public void setStatus(int status) { + this.status = status; + } + + public void setStatus(int status, String errorMessage) { + this.status = status; + this.errorMessage = errorMessage; + } + + public int getStatus() { + return this.status; + } + + public String getErrorMessage() { + return this.errorMessage; + } + + + //--------------------------------------------------------------------- + // Methods for MockRequestDispatcher + //--------------------------------------------------------------------- + + public void setForwardedUrl(String forwardedUrl) { + this.forwardedUrl = forwardedUrl; + } + + public String getForwardedUrl() { + return this.forwardedUrl; + } + + public void setIncludedUrl(String includedUrl) { + this.includedUrl = includedUrl; + } + + public String getIncludedUrl() { + return this.includedUrl; + } + + + /** + * Inner class that adapts the ServletOutputStream to mark the + * response as committed once the buffer size is exceeded. + */ + private class ResponseServletOutputStream extends DelegatingServletOutputStream { + + public ResponseServletOutputStream(OutputStream out) { + super(out); + } + + public void write(int b) throws IOException { + super.write(b); + super.flush(); + setCommittedIfBufferSizeExceeded(); + } + + public void flush() throws IOException { + super.flush(); + setCommitted(true); + } + } + + + /** + * Inner class that adapts the PrintWriter to mark the + * response as committed once the buffer size is exceeded. + */ + private class ResponsePrintWriter extends PrintWriter { + + public ResponsePrintWriter(Writer out) { + super(out, true); + } + + public void write(char buf[], int off, int len) { + super.write(buf, off, len); + super.flush(); + setCommittedIfBufferSizeExceeded(); + } + + public void write(String s, int off, int len) { + super.write(s, off, len); + super.flush(); + setCommittedIfBufferSizeExceeded(); + } + + public void write(int c) { + super.write(c); + super.flush(); + setCommittedIfBufferSizeExceeded(); + } + + public void flush() { + super.flush(); + setCommitted(true); + } + } + +} \ No newline at end of file diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockHttpSession.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockHttpSession.java new file mode 100644 index 0000000000..020c60e4c2 --- /dev/null +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockHttpSession.java @@ -0,0 +1,245 @@ +/* + * Copyright 2002-2007 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.mock.web; + +import java.io.Serializable; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Map; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpSession; +import javax.servlet.http.HttpSessionBindingEvent; +import javax.servlet.http.HttpSessionBindingListener; +import javax.servlet.http.HttpSessionContext; + +import org.springframework.util.Assert; + +/** + * Mock implementation of the {@link javax.servlet.http.HttpSession} interface. + * Supports the Servlet 2.4 API level. + * + *

Used for testing the web framework; also useful for testing + * application controllers. + * + * @author Juergen Hoeller + * @author Rod Johnson + * @author Mark Fisher + * @since 1.0.2 + */ +public class MockHttpSession implements HttpSession { + + public static final String SESSION_COOKIE_NAME = "JSESSION"; + + private static int nextId = 1; + + + private final String id; + + private final long creationTime = System.currentTimeMillis(); + + private int maxInactiveInterval; + + private long lastAccessedTime = System.currentTimeMillis(); + + private final ServletContext servletContext; + + private final Hashtable attributes = new Hashtable(); + + private boolean invalid = false; + + private boolean isNew = true; + + + /** + * Create a new MockHttpSession with a default {@link org.springframework.mock.web.MockServletContext}. + * @see org.springframework.mock.web.MockServletContext + */ + public MockHttpSession() { + this(null); + } + + /** + * Create a new MockHttpSession. + * @param servletContext the ServletContext that the session runs in + */ + public MockHttpSession(ServletContext servletContext) { + this(servletContext, null); + } + + /** + * Create a new MockHttpSession. + * @param servletContext the ServletContext that the session runs in + * @param id a unique identifier for this session + */ + public MockHttpSession(ServletContext servletContext, String id) { + this.servletContext = (servletContext != null ? servletContext : new MockServletContext()); + this.id = (id != null ? id : Integer.toString(nextId++)); + } + + + public long getCreationTime() { + return this.creationTime; + } + + public String getId() { + return this.id; + } + + public void access() { + this.lastAccessedTime = System.currentTimeMillis(); + this.isNew = false; + } + + public long getLastAccessedTime() { + return this.lastAccessedTime; + } + + public ServletContext getServletContext() { + return this.servletContext; + } + + public void setMaxInactiveInterval(int interval) { + this.maxInactiveInterval = interval; + } + + public int getMaxInactiveInterval() { + return this.maxInactiveInterval; + } + + public HttpSessionContext getSessionContext() { + throw new UnsupportedOperationException("getSessionContext"); + } + + public Object getAttribute(String name) { + Assert.notNull(name, "Attribute name must not be null"); + return this.attributes.get(name); + } + + public Object getValue(String name) { + return getAttribute(name); + } + + public Enumeration getAttributeNames() { + return this.attributes.keys(); + } + + public String[] getValueNames() { + return (String[]) this.attributes.keySet().toArray(new String[this.attributes.size()]); + } + + public void setAttribute(String name, Object value) { + Assert.notNull(name, "Attribute name must not be null"); + if (value != null) { + this.attributes.put(name, value); + if (value instanceof HttpSessionBindingListener) { + ((HttpSessionBindingListener) value).valueBound(new HttpSessionBindingEvent(this, name, value)); + } + } + else { + removeAttribute(name); + } + } + + public void putValue(String name, Object value) { + setAttribute(name, value); + } + + public void removeAttribute(String name) { + Assert.notNull(name, "Attribute name must not be null"); + Object value = this.attributes.remove(name); + if (value instanceof HttpSessionBindingListener) { + ((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value)); + } + } + + public void removeValue(String name) { + removeAttribute(name); + } + + /** + * Clear all of this session's attributes. + */ + public void clearAttributes() { + for (Iterator it = this.attributes.entrySet().iterator(); it.hasNext();) { + Map.Entry entry = (Map.Entry) it.next(); + String name = (String) entry.getKey(); + Object value = entry.getValue(); + it.remove(); + if (value instanceof HttpSessionBindingListener) { + ((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value)); + } + } + } + + public void invalidate() { + this.invalid = true; + clearAttributes(); + } + + public boolean isInvalid() { + return this.invalid; + } + + public void setNew(boolean value) { + this.isNew = value; + } + + public boolean isNew() { + return this.isNew; + } + + + /** + * Serialize the attributes of this session into an object that can + * be turned into a byte array with standard Java serialization. + * @return a representation of this session's serialized state + */ + public Serializable serializeState() { + HashMap state = new HashMap(); + for (Iterator it = this.attributes.entrySet().iterator(); it.hasNext();) { + Map.Entry entry = (Map.Entry) it.next(); + String name = (String) entry.getKey(); + Object value = entry.getValue(); + it.remove(); + if (value instanceof Serializable) { + state.put(name, value); + } + else { + // Not serializable... Servlet containers usually automatically + // unbind the attribute in this case. + if (value instanceof HttpSessionBindingListener) { + ((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value)); + } + } + } + return state; + } + + /** + * Deserialize the attributes of this session from a state object + * created by {@link #serializeState()}. + * @param state a representation of this session's serialized state + */ + public void deserializeState(Serializable state) { + Assert.isTrue(state instanceof Map, "Serialized state needs to be of type [java.util.Map]"); + this.attributes.putAll((Map) state); + } + +} \ No newline at end of file diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockRequestDispatcher.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockRequestDispatcher.java new file mode 100644 index 0000000000..34cf92338a --- /dev/null +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockRequestDispatcher.java @@ -0,0 +1,91 @@ +/* + * Copyright 2002-2007 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.mock.web; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponseWrapper; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.util.Assert; + +/** + * Mock implementation of the {@link javax.servlet.RequestDispatcher} interface. + * + *

Used for testing the web framework; typically not necessary for + * testing application controllers. + * + * @author Rod Johnson + * @author Juergen Hoeller + * @since 1.0.2 + */ +public class MockRequestDispatcher implements RequestDispatcher { + + private final Log logger = LogFactory.getLog(getClass()); + + private final String url; + + + /** + * Create a new MockRequestDispatcher for the given URL. + * @param url the URL to dispatch to. + */ + public MockRequestDispatcher(String url) { + Assert.notNull(url, "URL must not be null"); + this.url = url; + } + + + public void forward(ServletRequest request, ServletResponse response) { + Assert.notNull(request, "Request must not be null"); + Assert.notNull(response, "Response must not be null"); + if (response.isCommitted()) { + throw new IllegalStateException("Cannot perform forward - response is already committed"); + } + getMockHttpServletResponse(response).setForwardedUrl(this.url); + if (logger.isDebugEnabled()) { + logger.debug("MockRequestDispatcher: forwarding to URL [" + this.url + "]"); + } + } + + public void include(ServletRequest request, ServletResponse response) { + Assert.notNull(request, "Request must not be null"); + Assert.notNull(response, "Response must not be null"); + getMockHttpServletResponse(response).setIncludedUrl(this.url); + if (logger.isDebugEnabled()) { + logger.debug("MockRequestDispatcher: including URL [" + this.url + "]"); + } + } + + /** + * Obtain the underlying MockHttpServletResponse, + * unwrapping {@link javax.servlet.http.HttpServletResponseWrapper} decorators if necessary. + */ + protected MockHttpServletResponse getMockHttpServletResponse(ServletResponse response) { + if (response instanceof MockHttpServletResponse) { + return (MockHttpServletResponse) response; + } + if (response instanceof HttpServletResponseWrapper) { + return getMockHttpServletResponse(((HttpServletResponseWrapper) response).getResponse()); + } + throw new IllegalArgumentException("MockRequestDispatcher requires MockHttpServletResponse"); + } + +} \ No newline at end of file diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockServletConfig.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockServletConfig.java new file mode 100644 index 0000000000..8a492a54ab --- /dev/null +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockServletConfig.java @@ -0,0 +1,102 @@ +/* + * Copyright 2002-2006 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.mock.web; + +import java.util.Enumeration; +import java.util.Properties; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; + +import org.springframework.util.Assert; + +/** + * Mock implementation of the {@link javax.servlet.ServletConfig} interface. + * + *

Used for testing the web framework; typically not necessary for + * testing application controllers. + * + * @author Rod Johnson + * @author Juergen Hoeller + * @since 1.0.2 + */ +public class MockServletConfig implements ServletConfig { + + private final ServletContext servletContext; + + private final String servletName; + + private final Properties initParameters = new Properties(); + + + /** + * Create a new MockServletConfig with a default {@link org.springframework.mock.web.MockServletContext}. + */ + public MockServletConfig() { + this(null, ""); + } + + /** + * Create a new MockServletConfig with a default {@link org.springframework.mock.web.MockServletContext}. + * @param servletName the name of the servlet + */ + public MockServletConfig(String servletName) { + this(null, servletName); + } + + /** + * Create a new MockServletConfig. + * @param servletContext the ServletContext that the servlet runs in + */ + public MockServletConfig(ServletContext servletContext) { + this(servletContext, ""); + } + + /** + * Create a new MockServletConfig. + * @param servletContext the ServletContext that the servlet runs in + * @param servletName the name of the servlet + */ + public MockServletConfig(ServletContext servletContext, String servletName) { + this.servletContext = (servletContext != null ? servletContext : new MockServletContext()); + this.servletName = servletName; + } + + + public String getServletName() { + return servletName; + } + + public ServletContext getServletContext() { + return servletContext; + } + + public void addInitParameter(String name, String value) { + Assert.notNull(name, "Parameter name must not be null"); + this.initParameters.setProperty(name, value); + } + + public String getInitParameter(String name) { + Assert.notNull(name, "Parameter name must not be null"); + return this.initParameters.getProperty(name); + } + + public Enumeration getInitParameterNames() { + return this.initParameters.keys(); + } + +} \ No newline at end of file diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockServletContext.java b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockServletContext.java new file mode 100644 index 0000000000..b477ee0a12 --- /dev/null +++ b/org.springframework.web.servlet/src/test/java/org/springframework/mock/web/MockServletContext.java @@ -0,0 +1,356 @@ +/* + * Copyright 2002-2007 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.mock.web; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import javax.activation.FileTypeMap; +import javax.servlet.RequestDispatcher; +import javax.servlet.Servlet; +import javax.servlet.ServletContext; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.springframework.core.io.DefaultResourceLoader; +import org.springframework.core.io.Resource; +import org.springframework.core.io.ResourceLoader; +import org.springframework.util.Assert; +import org.springframework.util.ObjectUtils; +import org.springframework.web.util.WebUtils; + +/** + * Mock implementation of the {@link javax.servlet.ServletContext} interface. + * + *

Used for testing the Spring web framework; only rarely necessary for testing + * application controllers. As long as application components don't explicitly + * access the ServletContext, ClassPathXmlApplicationContext or + * FileSystemXmlApplicationContext can be used to load the context files for testing, + * even for DispatcherServlet context definitions. + * + *

For setting up a full WebApplicationContext in a test environment, you can + * use XmlWebApplicationContext (or GenericWebApplicationContext), passing in an + * appropriate MockServletContext instance. You might want to configure your + * MockServletContext with a FileSystemResourceLoader in that case, to make your + * resource paths interpreted as relative file system locations. + * + *

A common setup is to point your JVM working directory to the root of your + * web application directory, in combination with filesystem-based resource loading. + * This allows to load the context files as used in the web application, with + * relative paths getting interpreted correctly. Such a setup will work with both + * FileSystemXmlApplicationContext (which will load straight from the file system) + * and XmlWebApplicationContext with an underlying MockServletContext (as long as + * the MockServletContext has been configured with a FileSystemResourceLoader). + * + * @author Rod Johnson + * @author Juergen Hoeller + * @since 1.0.2 + * @see #MockServletContext(org.springframework.core.io.ResourceLoader) + * @see org.springframework.web.context.support.XmlWebApplicationContext + * @see org.springframework.web.context.support.GenericWebApplicationContext + * @see org.springframework.context.support.ClassPathXmlApplicationContext + * @see org.springframework.context.support.FileSystemXmlApplicationContext + */ +public class MockServletContext implements ServletContext { + + private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir"; + + + private final Log logger = LogFactory.getLog(getClass()); + + private final ResourceLoader resourceLoader; + + private final String resourceBasePath; + + private String contextPath = ""; + + private final Map contexts = new HashMap(); + + private final Properties initParameters = new Properties(); + + private final Hashtable attributes = new Hashtable(); + + private String servletContextName = "MockServletContext"; + + + /** + * Create a new MockServletContext, using no base path and a + * DefaultResourceLoader (i.e. the classpath root as WAR root). + * @see org.springframework.core.io.DefaultResourceLoader + */ + public MockServletContext() { + this("", null); + } + + /** + * Create a new MockServletContext, using a DefaultResourceLoader. + * @param resourceBasePath the WAR root directory (should not end with a slash) + * @see org.springframework.core.io.DefaultResourceLoader + */ + public MockServletContext(String resourceBasePath) { + this(resourceBasePath, null); + } + + /** + * Create a new MockServletContext, using the specified ResourceLoader + * and no base path. + * @param resourceLoader the ResourceLoader to use (or null for the default) + */ + public MockServletContext(ResourceLoader resourceLoader) { + this("", resourceLoader); + } + + /** + * Create a new MockServletContext. + * @param resourceBasePath the WAR root directory (should not end with a slash) + * @param resourceLoader the ResourceLoader to use (or null for the default) + */ + public MockServletContext(String resourceBasePath, ResourceLoader resourceLoader) { + this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader()); + this.resourceBasePath = (resourceBasePath != null ? resourceBasePath : ""); + + // Use JVM temp dir as ServletContext temp dir. + String tempDir = System.getProperty(TEMP_DIR_SYSTEM_PROPERTY); + if (tempDir != null) { + this.attributes.put(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File(tempDir)); + } + } + + + /** + * Build a full resource location for the given path, + * prepending the resource base path of this MockServletContext. + * @param path the path as specified + * @return the full resource path + */ + protected String getResourceLocation(String path) { + if (!path.startsWith("/")) { + path = "/" + path; + } + return this.resourceBasePath + path; + } + + + public void setContextPath(String contextPath) { + this.contextPath = (contextPath != null ? contextPath : ""); + } + + /* This is a Servlet API 2.5 method. */ + public String getContextPath() { + return this.contextPath; + } + + public void registerContext(String contextPath, ServletContext context) { + this.contexts.put(contextPath, context); + } + + public ServletContext getContext(String contextPath) { + if (this.contextPath.equals(contextPath)) { + return this; + } + return (ServletContext) this.contexts.get(contextPath); + } + + public int getMajorVersion() { + return 2; + } + + public int getMinorVersion() { + return 5; + } + + public String getMimeType(String filePath) { + return MimeTypeResolver.getMimeType(filePath); + } + + public Set getResourcePaths(String path) { + String actualPath = (path.endsWith("/") ? path : path + "/"); + Resource resource = this.resourceLoader.getResource(getResourceLocation(actualPath)); + try { + File file = resource.getFile(); + String[] fileList = file.list(); + if (ObjectUtils.isEmpty(fileList)) { + return null; + } + Set resourcePaths = new LinkedHashSet(fileList.length); + for (int i = 0; i < fileList.length; i++) { + String resultPath = actualPath + fileList[i]; + if (resource.createRelative(fileList[i]).getFile().isDirectory()) { + resultPath += "/"; + } + resourcePaths.add(resultPath); + } + return resourcePaths; + } + catch (IOException ex) { + logger.warn("Couldn't get resource paths for " + resource, ex); + return null; + } + } + + public URL getResource(String path) throws MalformedURLException { + Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); + if (!resource.exists()) { + return null; + } + try { + return resource.getURL(); + } + catch (MalformedURLException ex) { + throw ex; + } + catch (IOException ex) { + logger.warn("Couldn't get URL for " + resource, ex); + return null; + } + } + + public InputStream getResourceAsStream(String path) { + Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); + if (!resource.exists()) { + return null; + } + try { + return resource.getInputStream(); + } + catch (IOException ex) { + logger.warn("Couldn't open InputStream for " + resource, ex); + return null; + } + } + + public RequestDispatcher getRequestDispatcher(String path) { + if (!path.startsWith("/")) { + throw new IllegalArgumentException("RequestDispatcher path at ServletContext level must start with '/'"); + } + return new MockRequestDispatcher(path); + } + + public RequestDispatcher getNamedDispatcher(String path) { + return null; + } + + public Servlet getServlet(String name) { + return null; + } + + public Enumeration getServlets() { + return Collections.enumeration(Collections.EMPTY_SET); + } + + public Enumeration getServletNames() { + return Collections.enumeration(Collections.EMPTY_SET); + } + + public void log(String message) { + logger.info(message); + } + + public void log(Exception ex, String message) { + logger.info(message, ex); + } + + public void log(String message, Throwable ex) { + logger.info(message, ex); + } + + public String getRealPath(String path) { + Resource resource = this.resourceLoader.getResource(getResourceLocation(path)); + try { + return resource.getFile().getAbsolutePath(); + } + catch (IOException ex) { + logger.warn("Couldn't determine real path of resource " + resource, ex); + return null; + } + } + + public String getServerInfo() { + return "MockServletContext"; + } + + public String getInitParameter(String name) { + Assert.notNull(name, "Parameter name must not be null"); + return this.initParameters.getProperty(name); + } + + public void addInitParameter(String name, String value) { + Assert.notNull(name, "Parameter name must not be null"); + this.initParameters.setProperty(name, value); + } + + public Enumeration getInitParameterNames() { + return this.initParameters.keys(); + } + + public Object getAttribute(String name) { + Assert.notNull(name, "Attribute name must not be null"); + return this.attributes.get(name); + } + + public Enumeration getAttributeNames() { + return this.attributes.keys(); + } + + public void setAttribute(String name, Object value) { + Assert.notNull(name, "Attribute name must not be null"); + if (value != null) { + this.attributes.put(name, value); + } + else { + this.attributes.remove(name); + } + } + + public void removeAttribute(String name) { + Assert.notNull(name, "Attribute name must not be null"); + this.attributes.remove(name); + } + + public void setServletContextName(String servletContextName) { + this.servletContextName = servletContextName; + } + + public String getServletContextName() { + return this.servletContextName; + } + + + /** + * Inner factory class used to just introduce a Java Activation Framework + * dependency when actually asked to resolve a MIME type. + */ + private static class MimeTypeResolver { + + public static String getMimeType(String filePath) { + return FileTypeMap.getDefaultFileTypeMap().getContentType(filePath); + } + } + +} \ No newline at end of file diff --git a/org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/mvc/annotation/class-mapping.xml b/org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/mvc/annotation/class-mapping.xml new file mode 100644 index 0000000000..bd73342dc4 --- /dev/null +++ b/org.springframework.web.servlet/src/test/resources/org/springframework/web/servlet/mvc/annotation/class-mapping.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +