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..3a81051a75e 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.
@@ -16,6 +16,7 @@
package org.springframework.test.web.servlet;
+import java.util.Collections;
import java.util.List;
import javax.servlet.Filter;
import javax.servlet.ServletContext;
@@ -24,6 +25,7 @@ import javax.servlet.ServletException;
import org.springframework.core.NestedRuntimeException;
import org.springframework.mock.web.MockServletConfig;
import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.servlet.DispatcherServlet;
/**
* Base class for MockMvc builder implementations, providing the capability to
@@ -35,19 +37,34 @@ import org.springframework.web.context.WebApplicationContext;
*
* @author Rossen Stoyanchev
* @author Rob Winch
+ * @author Stephane Nicoll
* @since 3.2
*/
public abstract class MockMvcBuilderSupport {
+ @Deprecated
protected final MockMvc createMockMvc(Filter[] filters, MockServletConfig servletConfig,
WebApplicationContext webAppContext, RequestBuilder defaultRequestBuilder,
List globalResultMatchers, List globalResultHandlers,
Boolean dispatchOptions) {
+ return createMockMvc(filters, servletConfig, webAppContext, defaultRequestBuilder,
+ globalResultMatchers, globalResultHandlers,
+ Collections.singletonList(new DispatchOptionsDispatcherServletCustomizer(dispatchOptions)));
+ }
+
+ protected final MockMvc createMockMvc(Filter[] filters, MockServletConfig servletConfig,
+ WebApplicationContext webAppContext, RequestBuilder defaultRequestBuilder,
+ List globalResultMatchers, List globalResultHandlers,
+ 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);
}
@@ -72,4 +89,18 @@ public abstract class MockMvcBuilderSupport {
}
}
+ private static class DispatchOptionsDispatcherServletCustomizer
+ implements DispatcherServletCustomizer {
+ private final Boolean dispatchOptions;
+
+ private DispatchOptionsDispatcherServletCustomizer(Boolean dispatchOptions) {
+ this.dispatchOptions = dispatchOptions;
+ }
+
+ @Override
+ public void customize(DispatcherServlet dispatcherServlet) {
+ dispatcherServlet.setDispatchOptionsRequest(this.dispatchOptions);
+ }
+ }
+
}
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 50c4db84c27..58c847a57b1 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;
@@ -32,6 +33,7 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.request.RequestPostProcessor;
import org.springframework.util.Assert;
import org.springframework.web.context.WebApplicationContext;
+import org.springframework.web.servlet.DispatcherServlet;
/**
* An abstract implementation of {@link org.springframework.test.web.servlet.MockMvcBuilder}
@@ -42,6 +44,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 +58,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 +107,20 @@ 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(final boolean dispatchOptions) {
+ return addDispatcherServletCustomizer(new DispatcherServletCustomizer() {
+ @Override
+ public void customize(DispatcherServlet dispatcherServlet) {
+ dispatcherServlet.setDispatchOptionsRequest(dispatchOptions);
+ }
+ });
+ }
+
@SuppressWarnings("unchecked")
public final T apply(MockMvcConfigurer configurer) {
configurer.afterConfigurerAdded(this);
@@ -144,7 +156,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());
+ }
+
}