|
|
|
@ -1,5 +1,5 @@ |
|
|
|
/* |
|
|
|
/* |
|
|
|
* Copyright 2012-2020 the original author or authors. |
|
|
|
* Copyright 2012-2021 the original author or authors. |
|
|
|
* |
|
|
|
* |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
* you may not use this file except in compliance with the License. |
|
|
|
@ -17,13 +17,14 @@ |
|
|
|
package org.springframework.boot.autoconfigure.web.servlet; |
|
|
|
package org.springframework.boot.autoconfigure.web.servlet; |
|
|
|
|
|
|
|
|
|
|
|
import java.time.Duration; |
|
|
|
import java.time.Duration; |
|
|
|
import java.util.Arrays; |
|
|
|
import java.util.HashSet; |
|
|
|
import java.util.List; |
|
|
|
import java.util.List; |
|
|
|
import java.util.ListIterator; |
|
|
|
import java.util.ListIterator; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Optional; |
|
|
|
import java.util.Set; |
|
|
|
|
|
|
|
|
|
|
|
import javax.servlet.Servlet; |
|
|
|
import javax.servlet.Servlet; |
|
|
|
|
|
|
|
import javax.servlet.ServletContext; |
|
|
|
|
|
|
|
|
|
|
|
import org.apache.commons.logging.Log; |
|
|
|
import org.apache.commons.logging.Log; |
|
|
|
import org.apache.commons.logging.LogFactory; |
|
|
|
import org.apache.commons.logging.LogFactory; |
|
|
|
@ -70,10 +71,10 @@ import org.springframework.core.io.ResourceLoader; |
|
|
|
import org.springframework.core.task.AsyncTaskExecutor; |
|
|
|
import org.springframework.core.task.AsyncTaskExecutor; |
|
|
|
import org.springframework.format.FormatterRegistry; |
|
|
|
import org.springframework.format.FormatterRegistry; |
|
|
|
import org.springframework.format.support.FormattingConversionService; |
|
|
|
import org.springframework.format.support.FormattingConversionService; |
|
|
|
import org.springframework.http.CacheControl; |
|
|
|
|
|
|
|
import org.springframework.http.MediaType; |
|
|
|
import org.springframework.http.MediaType; |
|
|
|
import org.springframework.http.converter.HttpMessageConverter; |
|
|
|
import org.springframework.http.converter.HttpMessageConverter; |
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
import org.springframework.util.ClassUtils; |
|
|
|
|
|
|
|
import org.springframework.util.PathMatcher; |
|
|
|
import org.springframework.validation.DefaultMessageCodesResolver; |
|
|
|
import org.springframework.validation.DefaultMessageCodesResolver; |
|
|
|
import org.springframework.validation.MessageCodesResolver; |
|
|
|
import org.springframework.validation.MessageCodesResolver; |
|
|
|
import org.springframework.validation.Validator; |
|
|
|
import org.springframework.validation.Validator; |
|
|
|
@ -85,11 +86,13 @@ import org.springframework.web.bind.support.ConfigurableWebBindingInitializer; |
|
|
|
import org.springframework.web.context.request.NativeWebRequest; |
|
|
|
import org.springframework.web.context.request.NativeWebRequest; |
|
|
|
import org.springframework.web.context.request.RequestAttributes; |
|
|
|
import org.springframework.web.context.request.RequestAttributes; |
|
|
|
import org.springframework.web.context.request.RequestContextListener; |
|
|
|
import org.springframework.web.context.request.RequestContextListener; |
|
|
|
|
|
|
|
import org.springframework.web.context.support.ServletContextResource; |
|
|
|
import org.springframework.web.filter.FormContentFilter; |
|
|
|
import org.springframework.web.filter.FormContentFilter; |
|
|
|
import org.springframework.web.filter.HiddenHttpMethodFilter; |
|
|
|
import org.springframework.web.filter.HiddenHttpMethodFilter; |
|
|
|
import org.springframework.web.filter.RequestContextFilter; |
|
|
|
import org.springframework.web.filter.RequestContextFilter; |
|
|
|
import org.springframework.web.servlet.DispatcherServlet; |
|
|
|
import org.springframework.web.servlet.DispatcherServlet; |
|
|
|
import org.springframework.web.servlet.HandlerExceptionResolver; |
|
|
|
import org.springframework.web.servlet.HandlerExceptionResolver; |
|
|
|
|
|
|
|
import org.springframework.web.servlet.HandlerMapping; |
|
|
|
import org.springframework.web.servlet.LocaleResolver; |
|
|
|
import org.springframework.web.servlet.LocaleResolver; |
|
|
|
import org.springframework.web.servlet.View; |
|
|
|
import org.springframework.web.servlet.View; |
|
|
|
import org.springframework.web.servlet.ViewResolver; |
|
|
|
import org.springframework.web.servlet.ViewResolver; |
|
|
|
@ -104,6 +107,7 @@ import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry |
|
|
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; |
|
|
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; |
|
|
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
|
|
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; |
|
|
|
import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver; |
|
|
|
import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver; |
|
|
|
|
|
|
|
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping; |
|
|
|
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver; |
|
|
|
import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver; |
|
|
|
import org.springframework.web.servlet.i18n.FixedLocaleResolver; |
|
|
|
import org.springframework.web.servlet.i18n.FixedLocaleResolver; |
|
|
|
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver; |
|
|
|
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver; |
|
|
|
@ -111,12 +115,14 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl |
|
|
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; |
|
|
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; |
|
|
|
import org.springframework.web.servlet.resource.AppCacheManifestTransformer; |
|
|
|
import org.springframework.web.servlet.resource.AppCacheManifestTransformer; |
|
|
|
import org.springframework.web.servlet.resource.EncodedResourceResolver; |
|
|
|
import org.springframework.web.servlet.resource.EncodedResourceResolver; |
|
|
|
|
|
|
|
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; |
|
|
|
import org.springframework.web.servlet.resource.ResourceResolver; |
|
|
|
import org.springframework.web.servlet.resource.ResourceResolver; |
|
|
|
import org.springframework.web.servlet.resource.ResourceUrlProvider; |
|
|
|
import org.springframework.web.servlet.resource.ResourceUrlProvider; |
|
|
|
import org.springframework.web.servlet.resource.VersionResourceResolver; |
|
|
|
import org.springframework.web.servlet.resource.VersionResourceResolver; |
|
|
|
import org.springframework.web.servlet.view.BeanNameViewResolver; |
|
|
|
import org.springframework.web.servlet.view.BeanNameViewResolver; |
|
|
|
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver; |
|
|
|
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver; |
|
|
|
import org.springframework.web.servlet.view.InternalResourceViewResolver; |
|
|
|
import org.springframework.web.servlet.view.InternalResourceViewResolver; |
|
|
|
|
|
|
|
import org.springframework.web.util.UrlPathHelper; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* {@link EnableAutoConfiguration Auto-configuration} for {@link EnableWebMvc Web MVC}. |
|
|
|
* {@link EnableAutoConfiguration Auto-configuration} for {@link EnableWebMvc Web MVC}. |
|
|
|
@ -151,7 +157,7 @@ public class WebMvcAutoConfiguration { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static final String DEFAULT_SUFFIX = ""; |
|
|
|
public static final String DEFAULT_SUFFIX = ""; |
|
|
|
|
|
|
|
|
|
|
|
private static final String[] SERVLET_LOCATIONS = { "/" }; |
|
|
|
private static final String SERVLET_LOCATION = "/"; |
|
|
|
|
|
|
|
|
|
|
|
@Bean |
|
|
|
@Bean |
|
|
|
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class) |
|
|
|
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class) |
|
|
|
@ -167,13 +173,6 @@ public class WebMvcAutoConfiguration { |
|
|
|
return new OrderedFormContentFilter(); |
|
|
|
return new OrderedFormContentFilter(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static String[] getResourceLocations(String[] staticLocations) { |
|
|
|
|
|
|
|
String[] locations = new String[staticLocations.length + SERVLET_LOCATIONS.length]; |
|
|
|
|
|
|
|
System.arraycopy(staticLocations, 0, locations, 0, staticLocations.length); |
|
|
|
|
|
|
|
System.arraycopy(SERVLET_LOCATIONS, 0, locations, staticLocations.length, SERVLET_LOCATIONS.length); |
|
|
|
|
|
|
|
return locations; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Defined as a nested config to ensure WebMvcConfigurer is not read when not
|
|
|
|
// Defined as a nested config to ensure WebMvcConfigurer is not read when not
|
|
|
|
// on the classpath
|
|
|
|
// on the classpath
|
|
|
|
@Configuration(proxyBeanMethods = false) |
|
|
|
@Configuration(proxyBeanMethods = false) |
|
|
|
@ -182,26 +181,17 @@ public class WebMvcAutoConfiguration { |
|
|
|
@Order(0) |
|
|
|
@Order(0) |
|
|
|
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer { |
|
|
|
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer { |
|
|
|
|
|
|
|
|
|
|
|
private static final Log logger = LogFactory.getLog(WebMvcConfigurer.class); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final ResourceProperties resourceProperties; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final WebMvcProperties mvcProperties; |
|
|
|
private final WebMvcProperties mvcProperties; |
|
|
|
|
|
|
|
|
|
|
|
private final ListableBeanFactory beanFactory; |
|
|
|
private final ListableBeanFactory beanFactory; |
|
|
|
|
|
|
|
|
|
|
|
private final ObjectProvider<HttpMessageConverters> messageConvertersProvider; |
|
|
|
private final ObjectProvider<HttpMessageConverters> messageConvertersProvider; |
|
|
|
|
|
|
|
|
|
|
|
final ResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer; |
|
|
|
public WebMvcAutoConfigurationAdapter(WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, |
|
|
|
|
|
|
|
ObjectProvider<HttpMessageConverters> messageConvertersProvider) { |
|
|
|
public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebMvcProperties mvcProperties, |
|
|
|
|
|
|
|
ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider, |
|
|
|
|
|
|
|
ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider) { |
|
|
|
|
|
|
|
this.resourceProperties = resourceProperties; |
|
|
|
|
|
|
|
this.mvcProperties = mvcProperties; |
|
|
|
this.mvcProperties = mvcProperties; |
|
|
|
this.beanFactory = beanFactory; |
|
|
|
this.beanFactory = beanFactory; |
|
|
|
this.messageConvertersProvider = messageConvertersProvider; |
|
|
|
this.messageConvertersProvider = messageConvertersProvider; |
|
|
|
this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider.getIfAvailable(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
@ -303,37 +293,6 @@ public class WebMvcAutoConfiguration { |
|
|
|
ApplicationConversionService.addBeans(registry, this.beanFactory); |
|
|
|
ApplicationConversionService.addBeans(registry, this.beanFactory); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public void addResourceHandlers(ResourceHandlerRegistry registry) { |
|
|
|
|
|
|
|
if (!this.resourceProperties.isAddMappings()) { |
|
|
|
|
|
|
|
logger.debug("Default resource handling disabled"); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Duration cachePeriod = this.resourceProperties.getCache().getPeriod(); |
|
|
|
|
|
|
|
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl(); |
|
|
|
|
|
|
|
if (!registry.hasMappingForPattern("/webjars/**")) { |
|
|
|
|
|
|
|
customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**") |
|
|
|
|
|
|
|
.addResourceLocations("classpath:/META-INF/resources/webjars/") |
|
|
|
|
|
|
|
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
String staticPathPattern = this.mvcProperties.getStaticPathPattern(); |
|
|
|
|
|
|
|
if (!registry.hasMappingForPattern(staticPathPattern)) { |
|
|
|
|
|
|
|
customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern) |
|
|
|
|
|
|
|
.addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations())) |
|
|
|
|
|
|
|
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Integer getSeconds(Duration cachePeriod) { |
|
|
|
|
|
|
|
return (cachePeriod != null) ? (int) cachePeriod.getSeconds() : null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void customizeResourceHandlerRegistration(ResourceHandlerRegistration registration) { |
|
|
|
|
|
|
|
if (this.resourceHandlerRegistrationCustomizer != null) { |
|
|
|
|
|
|
|
this.resourceHandlerRegistrationCustomizer.customize(registration); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Bean |
|
|
|
@Bean |
|
|
|
@ConditionalOnMissingBean({ RequestContextListener.class, RequestContextFilter.class }) |
|
|
|
@ConditionalOnMissingBean({ RequestContextListener.class, RequestContextFilter.class }) |
|
|
|
@ConditionalOnMissingFilterBean(RequestContextFilter.class) |
|
|
|
@ConditionalOnMissingFilterBean(RequestContextFilter.class) |
|
|
|
@ -349,22 +308,31 @@ public class WebMvcAutoConfiguration { |
|
|
|
@Configuration(proxyBeanMethods = false) |
|
|
|
@Configuration(proxyBeanMethods = false) |
|
|
|
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware { |
|
|
|
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static final Log logger = LogFactory.getLog(WebMvcConfigurer.class); |
|
|
|
|
|
|
|
|
|
|
|
private final ResourceProperties resourceProperties; |
|
|
|
private final ResourceProperties resourceProperties; |
|
|
|
|
|
|
|
|
|
|
|
private final WebMvcProperties mvcProperties; |
|
|
|
private final WebMvcProperties mvcProperties; |
|
|
|
|
|
|
|
|
|
|
|
private final ListableBeanFactory beanFactory; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final WebMvcRegistrations mvcRegistrations; |
|
|
|
private final WebMvcRegistrations mvcRegistrations; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final ResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer; |
|
|
|
|
|
|
|
|
|
|
|
private ResourceLoader resourceLoader; |
|
|
|
private ResourceLoader resourceLoader; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final ListableBeanFactory beanFactory; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private final Set<String> autoConfiguredResourceHandlers = new HashSet<>(); |
|
|
|
|
|
|
|
|
|
|
|
public EnableWebMvcConfiguration(ResourceProperties resourceProperties, |
|
|
|
public EnableWebMvcConfiguration(ResourceProperties resourceProperties, |
|
|
|
ObjectProvider<WebMvcProperties> mvcPropertiesProvider, |
|
|
|
ObjectProvider<WebMvcProperties> mvcPropertiesProvider, |
|
|
|
ObjectProvider<WebMvcRegistrations> mvcRegistrationsProvider, ListableBeanFactory beanFactory) { |
|
|
|
ObjectProvider<WebMvcRegistrations> mvcRegistrationsProvider, |
|
|
|
|
|
|
|
ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider, |
|
|
|
|
|
|
|
ListableBeanFactory beanFactory) { |
|
|
|
this.resourceProperties = resourceProperties; |
|
|
|
this.resourceProperties = resourceProperties; |
|
|
|
this.mvcProperties = mvcPropertiesProvider.getIfAvailable(); |
|
|
|
this.mvcProperties = mvcPropertiesProvider.getIfAvailable(); |
|
|
|
this.mvcRegistrations = mvcRegistrationsProvider.getIfUnique(); |
|
|
|
this.mvcRegistrations = mvcRegistrationsProvider.getIfUnique(); |
|
|
|
|
|
|
|
this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider.getIfAvailable(); |
|
|
|
this.beanFactory = beanFactory; |
|
|
|
this.beanFactory = beanFactory; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -401,6 +369,72 @@ public class WebMvcAutoConfiguration { |
|
|
|
resourceUrlProvider); |
|
|
|
resourceUrlProvider); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Bean |
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
public HandlerMapping resourceHandlerMapping(UrlPathHelper urlPathHelper, PathMatcher pathMatcher, |
|
|
|
|
|
|
|
ContentNegotiationManager contentNegotiationManager, FormattingConversionService conversionService, |
|
|
|
|
|
|
|
ResourceUrlProvider resourceUrlProvider) { |
|
|
|
|
|
|
|
HandlerMapping mapping = super.resourceHandlerMapping(urlPathHelper, pathMatcher, contentNegotiationManager, |
|
|
|
|
|
|
|
conversionService, resourceUrlProvider); |
|
|
|
|
|
|
|
if (mapping instanceof SimpleUrlHandlerMapping) { |
|
|
|
|
|
|
|
addServletContextResourceHandlerMapping((SimpleUrlHandlerMapping) mapping); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return mapping; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void addServletContextResourceHandlerMapping(SimpleUrlHandlerMapping mapping) { |
|
|
|
|
|
|
|
Map<String, ?> urlMap = mapping.getUrlMap(); |
|
|
|
|
|
|
|
String pattern = this.mvcProperties.getStaticPathPattern(); |
|
|
|
|
|
|
|
Object handler = urlMap.get(pattern); |
|
|
|
|
|
|
|
if (handler instanceof ResourceHttpRequestHandler |
|
|
|
|
|
|
|
&& this.autoConfiguredResourceHandlers.contains(pattern)) { |
|
|
|
|
|
|
|
addServletContextResourceHandlerMapping((ResourceHttpRequestHandler) handler); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void addServletContextResourceHandlerMapping(ResourceHttpRequestHandler handler) { |
|
|
|
|
|
|
|
ServletContext servletContext = getServletContext(); |
|
|
|
|
|
|
|
if (servletContext != null) { |
|
|
|
|
|
|
|
List<Resource> locations = handler.getLocations(); |
|
|
|
|
|
|
|
locations.add(new ServletContextResource(servletContext, SERVLET_LOCATION)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
|
|
protected void addResourceHandlers(ResourceHandlerRegistry registry) { |
|
|
|
|
|
|
|
super.addResourceHandlers(registry); |
|
|
|
|
|
|
|
if (!this.resourceProperties.isAddMappings()) { |
|
|
|
|
|
|
|
logger.debug("Default resource handling disabled"); |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/"); |
|
|
|
|
|
|
|
addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), |
|
|
|
|
|
|
|
this.resourceProperties.getStaticLocations()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void addResourceHandler(ResourceHandlerRegistry registry, String pattern, String... locations) { |
|
|
|
|
|
|
|
if (registry.hasMappingForPattern(pattern)) { |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ResourceHandlerRegistration registration = registry.addResourceHandler(pattern); |
|
|
|
|
|
|
|
registration.addResourceLocations(locations); |
|
|
|
|
|
|
|
registration.setCachePeriod(getSeconds(this.resourceProperties.getCache().getPeriod())); |
|
|
|
|
|
|
|
registration.setCacheControl(this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl()); |
|
|
|
|
|
|
|
customizeResourceHandlerRegistration(registration); |
|
|
|
|
|
|
|
this.autoConfiguredResourceHandlers.add(pattern); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private Integer getSeconds(Duration cachePeriod) { |
|
|
|
|
|
|
|
return (cachePeriod != null) ? (int) cachePeriod.getSeconds() : null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void customizeResourceHandlerRegistration(ResourceHandlerRegistration registration) { |
|
|
|
|
|
|
|
if (this.resourceHandlerRegistrationCustomizer != null) { |
|
|
|
|
|
|
|
this.resourceHandlerRegistrationCustomizer.customize(registration); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Bean |
|
|
|
@Bean |
|
|
|
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, |
|
|
|
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, |
|
|
|
FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) { |
|
|
|
FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) { |
|
|
|
@ -412,22 +446,34 @@ public class WebMvcAutoConfiguration { |
|
|
|
return welcomePageHandlerMapping; |
|
|
|
return welcomePageHandlerMapping; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private Optional<Resource> getWelcomePage() { |
|
|
|
private Resource getWelcomePage() { |
|
|
|
String[] locations = getResourceLocations(this.resourceProperties.getStaticLocations()); |
|
|
|
for (String location : this.resourceProperties.getStaticLocations()) { |
|
|
|
return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst(); |
|
|
|
Resource indexHtml = getIndexHtml(location); |
|
|
|
|
|
|
|
if (indexHtml != null) { |
|
|
|
|
|
|
|
return indexHtml; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
ServletContext servletContext = getServletContext(); |
|
|
|
|
|
|
|
if (servletContext != null) { |
|
|
|
|
|
|
|
return getIndexHtml(new ServletContextResource(servletContext, SERVLET_LOCATION)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private Resource getIndexHtml(String location) { |
|
|
|
private Resource getIndexHtml(String location) { |
|
|
|
return this.resourceLoader.getResource(location + "index.html"); |
|
|
|
return getIndexHtml(this.resourceLoader.getResource(location)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private boolean isReadable(Resource resource) { |
|
|
|
private Resource getIndexHtml(Resource location) { |
|
|
|
try { |
|
|
|
try { |
|
|
|
return resource.exists() && (resource.getURL() != null); |
|
|
|
Resource resource = location.createRelative("index.html"); |
|
|
|
|
|
|
|
if (resource.exists() && (resource.getURL() != null)) { |
|
|
|
|
|
|
|
return resource; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
catch (Exception ex) { |
|
|
|
catch (Exception ex) { |
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Bean |
|
|
|
@Bean |
|
|
|
|