diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/DispatcherServletCustomizer.java b/spring-test/src/main/java/org/springframework/test/web/servlet/DispatcherServletCustomizer.java
new file mode 100644
index 00000000000..14ecb8d3ad2
--- /dev/null
+++ b/spring-test/src/main/java/org/springframework/test/web/servlet/DispatcherServletCustomizer.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2002-2016 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.test.web.servlet;
+
+import org.springframework.web.servlet.DispatcherServlet;
+
+/**
+ * Strategy interface for customizing {@link DispatcherServlet} instances that are
+ * managed by {@link MockMvc}.
+ *
+ * @author Stephane Nicoll
+ * @since 4.3.4
+ */
+public interface DispatcherServletCustomizer {
+
+ /**
+ * Customize the supplied {@link DispatcherServlet} before it is
+ * initialized.
+ * @param dispatcherServlet the dispatcher servlet to customize
+ */
+ void customize(DispatcherServlet dispatcherServlet);
+
+}
diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/MockMvcBuilderSupport.java b/spring-test/src/main/java/org/springframework/test/web/servlet/MockMvcBuilderSupport.java
index 046597a518e..db7c4a2984d 100644
--- a/spring-test/src/main/java/org/springframework/test/web/servlet/MockMvcBuilderSupport.java
+++ b/spring-test/src/main/java/org/springframework/test/web/servlet/MockMvcBuilderSupport.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2013 the original author or authors.
+ * Copyright 2002-2016 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.
@@ -35,6 +35,7 @@ import org.springframework.web.context.WebApplicationContext;
*
* @author Rossen Stoyanchev
* @author Rob Winch
+ * @author Stephane Nicoll
* @since 3.2
*/
public abstract class MockMvcBuilderSupport {
@@ -42,12 +43,16 @@ public abstract class MockMvcBuilderSupport {
protected final MockMvc createMockMvc(Filter[] filters, MockServletConfig servletConfig,
WebApplicationContext webAppContext, RequestBuilder defaultRequestBuilder,
List globalResultMatchers, List globalResultHandlers,
- Boolean dispatchOptions) {
+ List dispatcherServletCustomizers) {
ServletContext servletContext = webAppContext.getServletContext();
TestDispatcherServlet dispatcherServlet = new TestDispatcherServlet(webAppContext);
- dispatcherServlet.setDispatchOptionsRequest(dispatchOptions);
+ if (dispatcherServletCustomizers != null) {
+ for (DispatcherServletCustomizer customizers : dispatcherServletCustomizers) {
+ customizers.customize(dispatcherServlet);
+ }
+ }
try {
dispatcherServlet.init(servletConfig);
}
diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/AbstractMockMvcBuilder.java b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/AbstractMockMvcBuilder.java
index 98227c80f65..620c565ca9f 100644
--- a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/AbstractMockMvcBuilder.java
+++ b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/AbstractMockMvcBuilder.java
@@ -22,6 +22,7 @@ import javax.servlet.Filter;
import javax.servlet.ServletContext;
import org.springframework.mock.web.MockServletConfig;
+import org.springframework.test.web.servlet.DispatcherServletCustomizer;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MockMvcBuilderSupport;
import org.springframework.test.web.servlet.RequestBuilder;
@@ -42,6 +43,7 @@ import org.springframework.web.context.WebApplicationContext;
* pass to the DispatcherServlet.
*
* @author Rossen Stoyanchev
+ * @author Stephane Nicoll
* @since 4.0
*/
public abstract class AbstractMockMvcBuilder>
@@ -55,7 +57,7 @@ public abstract class AbstractMockMvcBuilder
private final List globalResultHandlers = new ArrayList<>();
- private Boolean dispatchOptions = Boolean.TRUE;
+ private final List dispatcherServletCustomizers = new ArrayList<>();
private final List configurers = new ArrayList<>(4);
@@ -104,11 +106,16 @@ public abstract class AbstractMockMvcBuilder
}
@SuppressWarnings("unchecked")
- public final T dispatchOptions(boolean dispatchOptions) {
- this.dispatchOptions = dispatchOptions;
+ public final T addDispatcherServletCustomizer(DispatcherServletCustomizer customizer) {
+ this.dispatcherServletCustomizers.add(customizer);
return (T) this;
}
+ public final T dispatchOptions(boolean dispatchOptions) {
+ return addDispatcherServletCustomizer(
+ dispatcherServlet -> dispatcherServlet.setDispatchOptionsRequest(dispatchOptions));
+ }
+
@SuppressWarnings("unchecked")
public final T apply(MockMvcConfigurer configurer) {
configurer.afterConfigurerAdded(this);
@@ -144,7 +151,7 @@ public abstract class AbstractMockMvcBuilder
Filter[] filterArray = this.filters.toArray(new Filter[this.filters.size()]);
return super.createMockMvc(filterArray, mockServletConfig, wac, this.defaultRequestBuilder,
- this.globalResultMatchers, this.globalResultHandlers, this.dispatchOptions);
+ this.globalResultMatchers, this.globalResultHandlers, this.dispatcherServletCustomizers);
}
/**
diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/setup/DefaultMockMvcBuilderTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/setup/DefaultMockMvcBuilderTests.java
index d30ad4180ae..d566fb54a69 100644
--- a/spring-test/src/test/java/org/springframework/test/web/servlet/setup/DefaultMockMvcBuilderTests.java
+++ b/spring-test/src/test/java/org/springframework/test/web/servlet/setup/DefaultMockMvcBuilderTests.java
@@ -20,11 +20,14 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import org.springframework.beans.DirectFieldAccessor;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.mock.web.MockServletContext;
+import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.StaticWebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
+import org.springframework.web.servlet.DispatcherServlet;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
@@ -36,6 +39,7 @@ import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*;
* @author Rob Winch
* @author Sebastien Deleuze
* @author Sam Brannen
+ * @author Stephane Nicoll
*/
public class DefaultMockMvcBuilderTests {
@@ -124,4 +128,32 @@ public class DefaultMockMvcBuilderTests {
assertSame(root, WebApplicationContextUtils.getRequiredWebApplicationContext(this.servletContext));
}
+ /**
+ * See /SPR-14277
+ */
+ @Test
+ public void dispatcherServletCustomizer() {
+ StubWebApplicationContext root = new StubWebApplicationContext(this.servletContext);
+ DefaultMockMvcBuilder builder = webAppContextSetup(root);
+ builder.addDispatcherServletCustomizer(ds -> ds.setContextId("test-id"));
+ builder.dispatchOptions(true);
+ MockMvc mvc = builder.build();
+ DispatcherServlet ds = (DispatcherServlet) new DirectFieldAccessor(mvc)
+ .getPropertyValue("servlet");
+ assertEquals("test-id", ds.getContextId());
+ }
+
+ @Test
+ public void dispatcherServletCustomizerProcessedInOrder() {
+ StubWebApplicationContext root = new StubWebApplicationContext(this.servletContext);
+ DefaultMockMvcBuilder builder = webAppContextSetup(root);
+ builder.addDispatcherServletCustomizer(ds -> ds.setContextId("test-id"));
+ builder.addDispatcherServletCustomizer(ds -> ds.setContextId("override-id"));
+ builder.dispatchOptions(true);
+ MockMvc mvc = builder.build();
+ DispatcherServlet ds = (DispatcherServlet) new DirectFieldAccessor(mvc)
+ .getPropertyValue("servlet");
+ assertEquals("override-id", ds.getContextId());
+ }
+
}