Merge branch '2.3.x' into 2.4.x
Closes gh-26622
This commit is contained in:
@@ -84,6 +84,7 @@ import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||
import org.springframework.web.accept.ContentNegotiationManager;
|
||||
import org.springframework.web.accept.ContentNegotiationStrategy;
|
||||
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
|
||||
import org.springframework.web.context.ServletContextAware;
|
||||
import org.springframework.web.context.request.NativeWebRequest;
|
||||
import org.springframework.web.context.request.RequestAttributes;
|
||||
import org.springframework.web.context.request.RequestContextListener;
|
||||
@@ -182,7 +183,11 @@ public class WebMvcAutoConfiguration {
|
||||
@EnableConfigurationProperties({ WebMvcProperties.class,
|
||||
org.springframework.boot.autoconfigure.web.ResourceProperties.class, WebProperties.class })
|
||||
@Order(0)
|
||||
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {
|
||||
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(WebMvcConfigurer.class);
|
||||
|
||||
private final Resources resourceProperties;
|
||||
|
||||
private final WebMvcProperties mvcProperties;
|
||||
|
||||
@@ -194,13 +199,19 @@ public class WebMvcAutoConfiguration {
|
||||
|
||||
private final ObjectProvider<ServletRegistrationBean<?>> servletRegistrations;
|
||||
|
||||
final ResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer;
|
||||
private final ResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer;
|
||||
|
||||
public WebMvcAutoConfigurationAdapter(WebProperties webProperties, WebMvcProperties mvcProperties,
|
||||
ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider,
|
||||
private ServletContext servletContext;
|
||||
|
||||
public WebMvcAutoConfigurationAdapter(
|
||||
org.springframework.boot.autoconfigure.web.ResourceProperties resourceProperties,
|
||||
WebProperties webProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory,
|
||||
ObjectProvider<HttpMessageConverters> messageConvertersProvider,
|
||||
ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,
|
||||
ObjectProvider<DispatcherServletPath> dispatcherServletPath,
|
||||
ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
|
||||
this.resourceProperties = resourceProperties.hasBeenCustomized() ? resourceProperties
|
||||
: webProperties.getResources();
|
||||
this.mvcProperties = mvcProperties;
|
||||
this.beanFactory = beanFactory;
|
||||
this.messageConvertersProvider = messageConvertersProvider;
|
||||
@@ -210,6 +221,11 @@ public class WebMvcAutoConfiguration {
|
||||
this.mvcProperties.checkConfiguration();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setServletContext(ServletContext servletContext) {
|
||||
this.servletContext = servletContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
this.messageConvertersProvider
|
||||
@@ -312,6 +328,49 @@ public class WebMvcAutoConfiguration {
|
||||
ApplicationConversionService.addBeans(registry, this.beanFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry 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(), (registration) -> {
|
||||
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
|
||||
if (this.servletContext != null) {
|
||||
ServletContextResource resource = new ServletContextResource(this.servletContext, SERVLET_LOCATION);
|
||||
registration.addResourceLocations(resource);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void addResourceHandler(ResourceHandlerRegistry registry, String pattern, String... locations) {
|
||||
addResourceHandler(registry, pattern, (registration) -> registration.addResourceLocations(locations));
|
||||
}
|
||||
|
||||
private void addResourceHandler(ResourceHandlerRegistry registry, String pattern,
|
||||
Consumer<ResourceHandlerRegistration> customizer) {
|
||||
if (registry.hasMappingForPattern(pattern)) {
|
||||
return;
|
||||
}
|
||||
ResourceHandlerRegistration registration = registry.addResourceHandler(pattern);
|
||||
customizer.accept(registration);
|
||||
registration.setCachePeriod(getSeconds(this.resourceProperties.getCache().getPeriod()));
|
||||
registration.setCacheControl(this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl());
|
||||
registration.setUseLastModified(this.resourceProperties.getCache().isUseLastModified());
|
||||
customizeResourceHandlerRegistration(registration);
|
||||
}
|
||||
|
||||
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
|
||||
@ConditionalOnMissingBean({ RequestContextListener.class, RequestContextFilter.class })
|
||||
@ConditionalOnMissingFilterBean(RequestContextFilter.class)
|
||||
@@ -328,8 +387,6 @@ public class WebMvcAutoConfiguration {
|
||||
@EnableConfigurationProperties(WebProperties.class)
|
||||
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(WebMvcConfigurer.class);
|
||||
|
||||
private final Resources resourceProperties;
|
||||
|
||||
private final WebMvcProperties mvcProperties;
|
||||
@@ -340,8 +397,6 @@ public class WebMvcAutoConfiguration {
|
||||
|
||||
private final WebMvcRegistrations mvcRegistrations;
|
||||
|
||||
private final ResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer;
|
||||
|
||||
private ResourceLoader resourceLoader;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@@ -356,7 +411,6 @@ public class WebMvcAutoConfiguration {
|
||||
this.mvcProperties = mvcProperties;
|
||||
this.webProperties = webProperties;
|
||||
this.mvcRegistrations = mvcRegistrationsProvider.getIfUnique();
|
||||
this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
|
||||
this.beanFactory = beanFactory;
|
||||
}
|
||||
|
||||
@@ -396,50 +450,6 @@ public class WebMvcAutoConfiguration {
|
||||
resourceUrlProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
super.addResourceHandlers(registry);
|
||||
if (!this.resourceProperties.isAddMappings()) {
|
||||
logger.debug("Default resource handling disabled");
|
||||
return;
|
||||
}
|
||||
ServletContext servletContext = getServletContext();
|
||||
addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
|
||||
addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
|
||||
registration.addResourceLocations(this.resourceProperties.getStaticLocations());
|
||||
if (servletContext != null) {
|
||||
registration.addResourceLocations(new ServletContextResource(servletContext, SERVLET_LOCATION));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void addResourceHandler(ResourceHandlerRegistry registry, String pattern, String... locations) {
|
||||
addResourceHandler(registry, pattern, (registration) -> registration.addResourceLocations(locations));
|
||||
}
|
||||
|
||||
private void addResourceHandler(ResourceHandlerRegistry registry, String pattern,
|
||||
Consumer<ResourceHandlerRegistration> customizer) {
|
||||
if (registry.hasMappingForPattern(pattern)) {
|
||||
return;
|
||||
}
|
||||
ResourceHandlerRegistration registration = registry.addResourceHandler(pattern);
|
||||
customizer.accept(registration);
|
||||
registration.setCachePeriod(getSeconds(this.resourceProperties.getCache().getPeriod()));
|
||||
registration.setCacheControl(this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl());
|
||||
registration.setUseLastModified(this.resourceProperties.getCache().isUseLastModified());
|
||||
customizeResourceHandlerRegistration(registration);
|
||||
}
|
||||
|
||||
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
|
||||
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
|
||||
FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
|
||||
|
||||
@@ -32,6 +32,7 @@ import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.validation.ValidatorFactory;
|
||||
@@ -52,9 +53,11 @@ import org.springframework.boot.context.properties.IncompatibleConfigurationExce
|
||||
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ContextConsumer;
|
||||
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
||||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
|
||||
import org.springframework.boot.web.server.WebServerFactoryCustomizerBeanPostProcessor;
|
||||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||
import org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext;
|
||||
import org.springframework.boot.web.servlet.filter.OrderedFormContentFilter;
|
||||
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
@@ -82,6 +85,7 @@ import org.springframework.web.accept.ContentNegotiationStrategy;
|
||||
import org.springframework.web.accept.ParameterContentNegotiationStrategy;
|
||||
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
|
||||
import org.springframework.web.context.request.ServletWebRequest;
|
||||
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||
import org.springframework.web.filter.FormContentFilter;
|
||||
import org.springframework.web.filter.HiddenHttpMethodFilter;
|
||||
@@ -99,6 +103,7 @@ import org.springframework.web.servlet.ViewResolver;
|
||||
import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
|
||||
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
|
||||
import org.springframework.web.servlet.config.annotation.CorsRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver;
|
||||
@@ -1005,6 +1010,25 @@ class WebMvcAutoConfigurationTests {
|
||||
(handler) -> assertThat(handler.isUseLastModified()).isFalse()));
|
||||
}
|
||||
|
||||
@Test // gh-25743
|
||||
void addResourceHandlersAppliesToChildAndParentContext() {
|
||||
try (AnnotationConfigServletWebServerApplicationContext context = new AnnotationConfigServletWebServerApplicationContext()) {
|
||||
context.register(WebMvcAutoConfiguration.class, DispatcherServletAutoConfiguration.class,
|
||||
HttpMessageConvertersAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
|
||||
ResourceHandlersWithChildAndParentContextConfiguration.class);
|
||||
context.refresh();
|
||||
SimpleUrlHandlerMapping resourceHandlerMapping = context.getBean("resourceHandlerMapping",
|
||||
SimpleUrlHandlerMapping.class);
|
||||
DispatcherServlet extraDispatcherServlet = context.getBean("extraDispatcherServlet",
|
||||
DispatcherServlet.class);
|
||||
SimpleUrlHandlerMapping extraResourceHandlerMapping = extraDispatcherServlet.getWebApplicationContext()
|
||||
.getBean("resourceHandlerMapping", SimpleUrlHandlerMapping.class);
|
||||
assertThat(resourceHandlerMapping).isNotSameAs(extraResourceHandlerMapping);
|
||||
assertThat(resourceHandlerMapping.getUrlMap()).containsKey("/**");
|
||||
assertThat(extraResourceHandlerMapping.getUrlMap()).containsKey("/**");
|
||||
}
|
||||
}
|
||||
|
||||
private void assertResourceHttpRequestHandler(AssertableWebApplicationContext context,
|
||||
Consumer<ResourceHttpRequestHandler> handlerConsumer) {
|
||||
Map<String, Object> handlerMap = getHandlerMap(context.getBean("resourceHandlerMapping", HandlerMapping.class));
|
||||
@@ -1459,7 +1483,6 @@ class WebMvcAutoConfigurationTests {
|
||||
|
||||
@Override
|
||||
public void setThemeName(HttpServletRequest request, HttpServletResponse response, String themeName) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1479,4 +1502,49 @@ class WebMvcAutoConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class ResourceHandlersWithChildAndParentContextConfiguration {
|
||||
|
||||
@Bean
|
||||
TomcatServletWebServerFactory webServerFactory() {
|
||||
return new TomcatServletWebServerFactory(0);
|
||||
}
|
||||
|
||||
@Bean
|
||||
ServletRegistrationBean<?> additionalDispatcherServlet(DispatcherServlet extraDispatcherServlet) {
|
||||
ServletRegistrationBean<?> registration = new ServletRegistrationBean<>(extraDispatcherServlet, "/extra/*");
|
||||
registration.setName("additionalDispatcherServlet");
|
||||
registration.setLoadOnStartup(1);
|
||||
return registration;
|
||||
}
|
||||
|
||||
@Bean
|
||||
private DispatcherServlet extraDispatcherServlet() throws ServletException {
|
||||
DispatcherServlet dispatcherServlet = new DispatcherServlet();
|
||||
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext();
|
||||
applicationContext.register(ResourceHandlersWithChildAndParentContextChildConfiguration.class);
|
||||
dispatcherServlet.setApplicationContext(applicationContext);
|
||||
return dispatcherServlet;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@EnableWebMvc
|
||||
static class ResourceHandlersWithChildAndParentContextChildConfiguration {
|
||||
|
||||
@Bean
|
||||
WebMvcConfigurer myConfigurer() {
|
||||
return new WebMvcConfigurer() {
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("/testtesttest");
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user