001/* 002 * Copyright 2002-2016 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.test.web.servlet; 018 019import java.util.Collections; 020import java.util.List; 021import javax.servlet.Filter; 022import javax.servlet.ServletContext; 023import javax.servlet.ServletException; 024 025import org.springframework.core.NestedRuntimeException; 026import org.springframework.mock.web.MockServletConfig; 027import org.springframework.web.context.WebApplicationContext; 028import org.springframework.web.servlet.DispatcherServlet; 029 030/** 031 * Base class for MockMvc builder implementations, providing the capability to 032 * create a {@link MockMvc} instance. 033 * 034 * <p>{@link org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder}, 035 * which derives from this class, provides a concrete {@code build} method, 036 * and delegates to abstract methods to obtain a {@link WebApplicationContext}. 037 * 038 * @author Rossen Stoyanchev 039 * @author Rob Winch 040 * @author Stephane Nicoll 041 * @since 3.2 042 */ 043public abstract class MockMvcBuilderSupport { 044 045 @Deprecated 046 protected final MockMvc createMockMvc(Filter[] filters, MockServletConfig servletConfig, 047 WebApplicationContext webAppContext, RequestBuilder defaultRequestBuilder, 048 List<ResultMatcher> globalResultMatchers, List<ResultHandler> globalResultHandlers, 049 Boolean dispatchOptions) { 050 return createMockMvc(filters, servletConfig, webAppContext, defaultRequestBuilder, 051 globalResultMatchers, globalResultHandlers, 052 Collections.<DispatcherServletCustomizer>singletonList(new DispatchOptionsDispatcherServletCustomizer(dispatchOptions))); 053 } 054 055 protected final MockMvc createMockMvc(Filter[] filters, MockServletConfig servletConfig, 056 WebApplicationContext webAppContext, RequestBuilder defaultRequestBuilder, 057 List<ResultMatcher> globalResultMatchers, List<ResultHandler> globalResultHandlers, 058 List<DispatcherServletCustomizer> dispatcherServletCustomizers) { 059 060 ServletContext servletContext = webAppContext.getServletContext(); 061 062 TestDispatcherServlet dispatcherServlet = new TestDispatcherServlet(webAppContext); 063 if (dispatcherServletCustomizers != null) { 064 for (DispatcherServletCustomizer customizers : dispatcherServletCustomizers) { 065 customizers.customize(dispatcherServlet); 066 } 067 } 068 try { 069 dispatcherServlet.init(servletConfig); 070 } 071 catch (ServletException ex) { 072 // should never happen.. 073 throw new MockMvcBuildException("Failed to initialize TestDispatcherServlet", ex); 074 } 075 076 MockMvc mockMvc = new MockMvc(dispatcherServlet, filters, servletContext); 077 mockMvc.setDefaultRequest(defaultRequestBuilder); 078 mockMvc.setGlobalResultMatchers(globalResultMatchers); 079 mockMvc.setGlobalResultHandlers(globalResultHandlers); 080 081 return mockMvc; 082 } 083 084 @SuppressWarnings("serial") 085 private static class MockMvcBuildException extends NestedRuntimeException { 086 087 public MockMvcBuildException(String msg, Throwable cause) { 088 super(msg, cause); 089 } 090 } 091 092 private static class DispatchOptionsDispatcherServletCustomizer 093 implements DispatcherServletCustomizer { 094 private final Boolean dispatchOptions; 095 096 private DispatchOptionsDispatcherServletCustomizer(Boolean dispatchOptions) { 097 this.dispatchOptions = dispatchOptions; 098 } 099 100 @Override 101 public void customize(DispatcherServlet dispatcherServlet) { 102 dispatcherServlet.setDispatchOptionsRequest(this.dispatchOptions); 103 } 104 } 105 106}