/* * Copyright 2012-2017 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.boot.autoconfigure.web.servlet; import java.net.URI; import javax.servlet.MultipartConfigElement; import org.junit.After; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.test.util.EnvironmentTestUtils; import org.springframework.boot.web.embedded.jetty.JettyServletWebServerFactory; import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory; import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.client.ClientHttpResponse; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.stereotype.Controller; import org.springframework.test.util.ReflectionTestUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.client.RestTemplate; import org.springframework.web.multipart.MultipartResolver; import org.springframework.web.multipart.support.StandardServletMultipartResolver; import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; /** * Tests for {@link MultipartAutoConfiguration}. Tests an empty configuration, no * multipart configuration, and a multipart configuration (with both Jetty and Tomcat). * * @author Greg Turnquist * @author Dave Syer * @author Josh Long * @author Ivan Sopov * @author Toshiaki Maki */ public class MultipartAutoConfigurationTests { private AnnotationConfigServletWebServerApplicationContext context; @Rule public ExpectedException thrown = ExpectedException.none(); @After public void close() { if (this.context != null) { this.context.close(); } } @Test public void webServerWithNothing() throws Exception { this.context = new AnnotationConfigServletWebServerApplicationContext( WebServerWithNothing.class, BaseConfiguration.class); DispatcherServlet servlet = this.context.getBean(DispatcherServlet.class); verify404(); assertThat(servlet.getMultipartResolver()).isNotNull(); assertThat(this.context.getBeansOfType(StandardServletMultipartResolver.class)) .hasSize(1); assertThat(this.context.getBeansOfType(MultipartResolver.class)).hasSize(1); } @Test public void webServerWithNoMultipartJettyConfiguration() { this.context = new AnnotationConfigServletWebServerApplicationContext( WebServerWithNoMultipartJetty.class, BaseConfiguration.class); DispatcherServlet servlet = this.context.getBean(DispatcherServlet.class); assertThat(servlet.getMultipartResolver()).isNotNull(); assertThat(this.context.getBeansOfType(StandardServletMultipartResolver.class)) .hasSize(1); assertThat(this.context.getBeansOfType(MultipartResolver.class)).hasSize(1); verifyServletWorks(); } @Test public void webServerWithNoMultipartUndertowConfiguration() { this.context = new AnnotationConfigServletWebServerApplicationContext( WebServerWithNoMultipartUndertow.class, BaseConfiguration.class); DispatcherServlet servlet = this.context.getBean(DispatcherServlet.class); verifyServletWorks(); assertThat(servlet.getMultipartResolver()).isNotNull(); assertThat(this.context.getBeansOfType(StandardServletMultipartResolver.class)) .hasSize(1); assertThat(this.context.getBeansOfType(MultipartResolver.class)).hasSize(1); } @Test public void webServerWithNoMultipartTomcatConfiguration() { this.context = new AnnotationConfigServletWebServerApplicationContext( WebServerWithNoMultipartTomcat.class, BaseConfiguration.class); DispatcherServlet servlet = this.context.getBean(DispatcherServlet.class); assertThat(servlet.getMultipartResolver()).isNull(); assertThat(this.context.getBeansOfType(StandardServletMultipartResolver.class)) .hasSize(1); assertThat(this.context.getBeansOfType(MultipartResolver.class)).hasSize(1); verifyServletWorks(); } @Test public void webServerWithAutomatedMultipartJettyConfiguration() { this.context = new AnnotationConfigServletWebServerApplicationContext( WebServerWithEverythingJetty.class, BaseConfiguration.class); this.context.getBean(MultipartConfigElement.class); assertThat(this.context.getBean(StandardServletMultipartResolver.class)).isSameAs( this.context.getBean(DispatcherServlet.class).getMultipartResolver()); verifyServletWorks(); } @Test public void webServerWithAutomatedMultipartTomcatConfiguration() throws Exception { this.context = new AnnotationConfigServletWebServerApplicationContext( WebServerWithEverythingTomcat.class, BaseConfiguration.class); new RestTemplate().getForObject( "http://localhost:" + this.context.getWebServer().getPort() + "/", String.class); this.context.getBean(MultipartConfigElement.class); assertThat(this.context.getBean(StandardServletMultipartResolver.class)).isSameAs( this.context.getBean(DispatcherServlet.class).getMultipartResolver()); verifyServletWorks(); } @Test public void webServerWithAutomatedMultipartUndertowConfiguration() { this.context = new AnnotationConfigServletWebServerApplicationContext( WebServerWithEverythingUndertow.class, BaseConfiguration.class); this.context.getBean(MultipartConfigElement.class); verifyServletWorks(); assertThat(this.context.getBean(StandardServletMultipartResolver.class)).isSameAs( this.context.getBean(DispatcherServlet.class).getMultipartResolver()); } @Test public void webServerWithMultipartConfigDisabled() { testWebServerWithCustomMultipartConfigEnabledSetting("false", 0); } @Test public void webServerWithMultipartConfigEnabled() { testWebServerWithCustomMultipartConfigEnabledSetting("true", 1); } private void testWebServerWithCustomMultipartConfigEnabledSetting( final String propertyValue, int expectedNumberOfMultipartConfigElementBeans) { this.context = new AnnotationConfigServletWebServerApplicationContext(); EnvironmentTestUtils.addEnvironment(this.context, "spring.servlet.multipart.enabled=" + propertyValue); this.context.register(WebServerWithNoMultipartTomcat.class, BaseConfiguration.class); this.context.refresh(); this.context.getBean(MultipartProperties.class); assertThat(this.context.getBeansOfType(MultipartConfigElement.class)) .hasSize(expectedNumberOfMultipartConfigElementBeans); } @Test public void webServerWithCustomMultipartResolver() throws Exception { this.context = new AnnotationConfigServletWebServerApplicationContext( WebServerWithCustomMultipartResolver.class, BaseConfiguration.class); MultipartResolver multipartResolver = this.context .getBean(MultipartResolver.class); assertThat(multipartResolver) .isNotInstanceOf(StandardServletMultipartResolver.class); } @Test public void configureResolveLazily() { this.context = new AnnotationConfigServletWebServerApplicationContext(); EnvironmentTestUtils.addEnvironment(this.context, "spring.servlet.multipart.resolve-lazily=true"); this.context.register(WebServerWithNothing.class, BaseConfiguration.class); this.context.refresh(); StandardServletMultipartResolver multipartResolver = this.context .getBean(StandardServletMultipartResolver.class); boolean resolveLazily = (Boolean) ReflectionTestUtils.getField(multipartResolver, "resolveLazily"); assertThat(resolveLazily).isTrue(); } private void verify404() throws Exception { HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(); ClientHttpRequest request = requestFactory .createRequest( new URI("http://localhost:" + this.context.getWebServer().getPort() + "/"), HttpMethod.GET); ClientHttpResponse response = request.execute(); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); } private void verifyServletWorks() { RestTemplate restTemplate = new RestTemplate(); String url = "http://localhost:" + this.context.getWebServer().getPort() + "/"; assertThat(restTemplate.getForObject(url, String.class)).isEqualTo("Hello"); } @Configuration public static class WebServerWithNothing { } @Configuration public static class WebServerWithNoMultipartJetty { @Bean JettyServletWebServerFactory webServerFactory() { return new JettyServletWebServerFactory(); } @Bean WebController controller() { return new WebController(); } } @Configuration public static class WebServerWithNoMultipartUndertow { @Bean UndertowServletWebServerFactory webServerFactory() { return new UndertowServletWebServerFactory(); } @Bean WebController controller() { return new WebController(); } } @Configuration @Import({ ServletWebServerFactoryAutoConfiguration.class, DispatcherServletAutoConfiguration.class, MultipartAutoConfiguration.class }) @EnableConfigurationProperties(MultipartProperties.class) protected static class BaseConfiguration { @Bean public ServerProperties serverProperties() { ServerProperties properties = new ServerProperties(); properties.setPort(0); return properties; } } @Configuration public static class WebServerWithNoMultipartTomcat { @Bean TomcatServletWebServerFactory webServerFactory() { return new TomcatServletWebServerFactory(); } @Bean WebController controller() { return new WebController(); } } @Configuration public static class WebServerWithEverythingJetty { @Bean MultipartConfigElement multipartConfigElement() { return new MultipartConfigElement(""); } @Bean JettyServletWebServerFactory webServerFactory() { return new JettyServletWebServerFactory(); } @Bean WebController webController() { return new WebController(); } } @Configuration @EnableWebMvc public static class WebServerWithEverythingTomcat { @Bean MultipartConfigElement multipartConfigElement() { return new MultipartConfigElement(""); } @Bean TomcatServletWebServerFactory webServerFactory() { return new TomcatServletWebServerFactory(); } @Bean WebController webController() { return new WebController(); } } @Configuration @EnableWebMvc public static class WebServerWithEverythingUndertow { @Bean MultipartConfigElement multipartConfigElement() { return new MultipartConfigElement(""); } @Bean UndertowServletWebServerFactory webServerFactory() { return new UndertowServletWebServerFactory(); } @Bean WebController webController() { return new WebController(); } } public static class WebServerWithCustomMultipartResolver { @Bean MultipartResolver multipartResolver() { return mock(MultipartResolver.class); } } @Controller public static class WebController { @RequestMapping("/") @ResponseBody public String index() { return "Hello"; } } }