diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java index 8cce36edb1..b11ca81f11 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java @@ -66,6 +66,7 @@ import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.LocaleResolver; import org.springframework.web.servlet.View; import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer; import org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; @@ -87,6 +88,7 @@ import org.springframework.web.servlet.view.InternalResourceViewResolver; * @author Phillip Webb * @author Dave Syer * @author Andy Wilkinson + * @author Sébastien Deleuze */ @Configuration @ConditionalOnWebApplication @@ -166,6 +168,14 @@ public class WebMvcAutoConfiguration { converters.addAll(this.messageConverters.getConverters()); } + @Override + public void configureAsyncSupport(AsyncSupportConfigurer configurer) { + Long timeout = this.mvcProperties.getAsync().getRequestTimeout(); + if (timeout != null) { + configurer.setDefaultTimeout(timeout); + } + } + @Bean @ConditionalOnMissingBean(InternalResourceViewResolver.class) public InternalResourceViewResolver defaultViewResolver() { diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcProperties.java index ecd6186742..072088aea1 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcProperties.java @@ -23,6 +23,7 @@ import org.springframework.validation.DefaultMessageCodesResolver; * {@link ConfigurationProperties properties} for Spring MVC. * * @author Phillip Webb + * @author Sébastien Deleuze * @since 1.1 */ @ConfigurationProperties("spring.mvc") @@ -49,6 +50,8 @@ public class WebMvcProperties { */ private boolean ignoreDefaultModelOnRedirect = true; + private final Async async = new Async(); + public DefaultMessageCodesResolver.Format getMessageCodesResolverFormat() { return this.messageCodesResolverFormat; } @@ -82,4 +85,26 @@ public class WebMvcProperties { this.ignoreDefaultModelOnRedirect = ignoreDefaultModelOnRedirect; } + public Async getAsync() { + return this.async; + } + + public static class Async { + + /** + * The amount of time (in milliseconds) before asynchronous request handling times + * out. If this value is not set, the default timeout of the underlying + * implementation is used, e.g. 10 seconds on Tomcat with Servlet 3. + */ + private Long requestTimeout; + + public Long getRequestTimeout() { + return this.requestTimeout; + } + + public void setRequestTimeout(Long requestTimeout) { + this.requestTimeout = requestTimeout; + } + + } } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfigurationTests.java index 601fbfdc38..81a3c07514 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfigurationTests.java @@ -385,6 +385,33 @@ public class WebMvcAutoConfigurationTests { "faviconHandlerMapping"), is(nullValue())); } + @Test + public void defaultAsyncRequestTimeout() throws Exception { + this.context = new AnnotationConfigEmbeddedWebApplicationContext(); + this.context.register(Config.class, WebMvcAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + this.context.refresh(); + RequestMappingHandlerAdapter adapter = this.context + .getBean(RequestMappingHandlerAdapter.class); + assertNull(ReflectionTestUtils.getField(adapter, "asyncRequestTimeout")); + } + + @Test + public void customAsyncRequestTimeout() throws Exception { + this.context = new AnnotationConfigEmbeddedWebApplicationContext(); + EnvironmentTestUtils.addEnvironment(this.context, + "spring.mvc.async.request-timeout:123456"); + this.context.register(Config.class, WebMvcAutoConfiguration.class, + HttpMessageConvertersAutoConfiguration.class, + PropertyPlaceholderAutoConfiguration.class); + this.context.refresh(); + RequestMappingHandlerAdapter adapter = this.context + .getBean(RequestMappingHandlerAdapter.class); + Object actual = ReflectionTestUtils.getField(adapter, "asyncRequestTimeout"); + assertEquals(123456L, actual); + } + @Configuration protected static class ViewConfig { diff --git a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index ffdccee48e..ecece86eba 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -120,7 +120,8 @@ content into your application; rather pick only the properties that you need. spring.mvc.date-format= # set fixed date format, e.g. dd/MM/yyyy spring.mvc.favicon.enabled=true spring.mvc.message-codes-resolver-format= # PREFIX_ERROR_CODE / POSTFIX_ERROR_CODE - spring.mvc.ignore-default-model-on-redirect=true # If the the content of the "default" model should be ignored redirects + spring.mvc.ignore-default-model-on-redirect=true # if the the content of the "default" model should be ignored redirects + spring.mvc.async.request-timeout= # async timeout in milliseconds spring.view.prefix= # MVC view prefix spring.view.suffix= # ... and suffix