diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractDispatcherServletInitializer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractDispatcherServletInitializer.java index 4b97870005..9f947c8895 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractDispatcherServletInitializer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/support/AbstractDispatcherServletInitializer.java @@ -30,6 +30,7 @@ import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; import org.springframework.web.context.AbstractContextLoaderInitializer; import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.filter.DelegatingFilterProxy; import org.springframework.web.servlet.DispatcherServlet; /** @@ -162,6 +163,16 @@ public abstract class AbstractDispatcherServletInitializer extends AbstractConte protected FilterRegistration.Dynamic registerServletFilter(ServletContext servletContext, Filter filter) { String filterName = Conventions.getVariableName(filter); Dynamic registration = servletContext.addFilter(filterName, filter); + if (registration == null) { + int counter = -1; + while (counter == -1 || registration == null) { + counter++; + registration = servletContext.addFilter(filterName + "#" + counter, filter); + Assert.isTrue(counter < 100, + "Failed to register filter '" + filter + "'." + + "Could the same Filter instance have been registered already?"); + } + } registration.setAsyncSupported(isAsyncSupported()); registration.addMappingForServletNames(getDispatcherTypes(), false, getServletName()); return registration; diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/AnnotationConfigDispatcherServletInitializerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/AnnotationConfigDispatcherServletInitializerTests.java index 6e023649fa..c4acf15b58 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/support/AnnotationConfigDispatcherServletInitializerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/support/AnnotationConfigDispatcherServletInitializerTests.java @@ -39,6 +39,7 @@ import org.springframework.mock.web.test.MockServletConfig; import org.springframework.mock.web.test.MockServletContext; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; +import org.springframework.web.filter.DelegatingFilterProxy; import org.springframework.web.filter.HiddenHttpMethodFilter; import org.springframework.web.servlet.DispatcherServlet; @@ -53,8 +54,6 @@ public class AnnotationConfigDispatcherServletInitializerTests { private static final String SERVLET_NAME = "myservlet"; - private static final String FILTER_NAME = "hiddenHttpMethodFilter"; - private static final String ROLE_NAME = "role"; private static final String SERVLET_MAPPING = "/myservlet"; @@ -106,14 +105,18 @@ public class AnnotationConfigDispatcherServletInitializerTests { assertEquals(ROLE_NAME, servletRegistration.getRunAsRole()); assertTrue(servletRegistration.isAsyncSupported()); - assertEquals(1, filterRegistrations.size()); - assertNotNull(filterRegistrations.get(FILTER_NAME)); + assertEquals(4, filterRegistrations.size()); + assertNotNull(filterRegistrations.get("hiddenHttpMethodFilter")); + assertNotNull(filterRegistrations.get("delegatingFilterProxy")); + assertNotNull(filterRegistrations.get("delegatingFilterProxy#0")); + assertNotNull(filterRegistrations.get("delegatingFilterProxy#1")); - MockFilterRegistration filterRegistration = filterRegistrations.get(FILTER_NAME); + for (MockFilterRegistration filterRegistration : filterRegistrations.values()) { + assertTrue(filterRegistration.isAsyncSupported()); + assertEquals(EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.ASYNC), + filterRegistration.getMappings().get(SERVLET_NAME)); + } - assertTrue(filterRegistration.isAsyncSupported()); - assertEquals(EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.ASYNC), - filterRegistration.getMappings().get(SERVLET_NAME)); } @Test @@ -130,10 +133,11 @@ public class AnnotationConfigDispatcherServletInitializerTests { MockServletRegistration servletRegistration = servletRegistrations.get(SERVLET_NAME); assertFalse(servletRegistration.isAsyncSupported()); - MockFilterRegistration filterRegistration = filterRegistrations.get(FILTER_NAME); - assertFalse(filterRegistration.isAsyncSupported()); - assertEquals(EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE), - filterRegistration.getMappings().get(SERVLET_NAME)); + for (MockFilterRegistration filterRegistration : filterRegistrations.values()) { + assertFalse(filterRegistration.isAsyncSupported()); + assertEquals(EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.INCLUDE), + filterRegistration.getMappings().get(SERVLET_NAME)); + } } // SPR-11357 @@ -188,6 +192,9 @@ public class AnnotationConfigDispatcherServletInitializerTests { @Override public ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet) { + if (servlets.containsKey(servletName)) { + return null; + } servlets.put(servletName, servlet); MockServletRegistration registration = new MockServletRegistration(); servletRegistrations.put(servletName, registration); @@ -196,6 +203,9 @@ public class AnnotationConfigDispatcherServletInitializerTests { @Override public Dynamic addFilter(String filterName, Filter filter) { + if (filters.containsKey(filterName)) { + return null; + } filters.put(filterName, filter); MockFilterRegistration registration = new MockFilterRegistration(); filterRegistrations.put(filterName, registration); @@ -224,7 +234,12 @@ public class AnnotationConfigDispatcherServletInitializerTests { @Override protected Filter[] getServletFilters() { - return new Filter[] { new HiddenHttpMethodFilter() }; + return new Filter[] { + new HiddenHttpMethodFilter(), + new DelegatingFilterProxy("a"), + new DelegatingFilterProxy("b"), + new DelegatingFilterProxy("c") + }; } @Override