diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/config/ResourceHandlerRegistry.java b/spring-webflux/src/main/java/org/springframework/web/reactive/config/ResourceHandlerRegistry.java index 19a25778ccb..6cad0ec58e8 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/config/ResourceHandlerRegistry.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/config/ResourceHandlerRegistry.java @@ -28,6 +28,8 @@ import org.springframework.core.io.ResourceLoader; import org.springframework.lang.Nullable; import org.springframework.web.reactive.handler.AbstractUrlHandlerMapping; import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping; +import org.springframework.web.reactive.resource.ResourceTransformerSupport; +import org.springframework.web.reactive.resource.ResourceUrlProvider; import org.springframework.web.reactive.resource.ResourceWebHandler; import org.springframework.web.server.WebHandler; @@ -49,6 +51,7 @@ import org.springframework.web.server.WebHandler; * period for served resources. * * @author Rossen Stoyanchev + * @author Brian Clozel * @since 5.0 */ public class ResourceHandlerRegistry { @@ -57,7 +60,10 @@ public class ResourceHandlerRegistry { private final List registrations = new ArrayList<>(); - private int order = Ordered.LOWEST_PRECEDENCE -1; + private int order = Ordered.LOWEST_PRECEDENCE - 1; + + @Nullable + private ResourceUrlProvider resourceUrlProvider; /** @@ -69,6 +75,17 @@ public class ResourceHandlerRegistry { this.resourceLoader = resourceLoader; } + /** + * Configure the {@link ResourceUrlProvider} that can be used by + * {@link org.springframework.web.reactive.resource.ResourceTransformer} instances. + * @param resourceUrlProvider the resource URL provider to use + * @since 5.1.2 + */ + public void setResourceUrlProvider(@Nullable ResourceUrlProvider resourceUrlProvider) { + this.resourceUrlProvider = resourceUrlProvider; + } + + /** * Add a resource handler for serving static resources based on the specified @@ -121,6 +138,11 @@ public class ResourceHandlerRegistry { for (ResourceHandlerRegistration registration : this.registrations) { for (String pathPattern : registration.getPathPatterns()) { ResourceWebHandler handler = registration.getRequestHandler(); + handler.getResourceTransformers().forEach(transformer -> { + if (transformer instanceof ResourceTransformerSupport) { + ((ResourceTransformerSupport) transformer).setResourceUrlProvider(this.resourceUrlProvider); + } + }); try { handler.afterPropertiesSet(); } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurationSupport.java b/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurationSupport.java index 3fa7a9cc578..d93878cd9fc 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurationSupport.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurationSupport.java @@ -55,6 +55,7 @@ import org.springframework.web.reactive.function.server.support.RouterFunctionMa import org.springframework.web.reactive.function.server.support.ServerResponseResultHandler; import org.springframework.web.reactive.handler.AbstractHandlerMapping; import org.springframework.web.reactive.handler.WebFluxResponseStatusExceptionHandler; +import org.springframework.web.reactive.resource.ResourceUrlProvider; import org.springframework.web.reactive.result.SimpleHandlerAdapter; import org.springframework.web.reactive.result.method.annotation.ArgumentResolverConfigurer; import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter; @@ -74,6 +75,7 @@ import org.springframework.web.server.i18n.LocaleContextResolver; *

Import directly or extend and override protected methods to customize. * * @author Rossen Stoyanchev + * @author Brian Clozel * @since 5.0 */ public class WebFluxConfigurationSupport implements ApplicationContextAware { @@ -229,6 +231,7 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware { resourceLoader = new DefaultResourceLoader(); } ResourceHandlerRegistry registry = new ResourceHandlerRegistry(resourceLoader); + registry.setResourceUrlProvider(resourceUrlProvider()); addResourceHandlers(registry); AbstractHandlerMapping handlerMapping = registry.getHandlerMapping(); @@ -249,6 +252,11 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware { return handlerMapping; } + @Bean + public ResourceUrlProvider resourceUrlProvider() { + return new ResourceUrlProvider(); + } + /** * Override this method to add resource handlers for serving static resources. * @see ResourceHandlerRegistry diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/config/ResourceHandlerRegistryTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/config/ResourceHandlerRegistryTests.java index 0dbc0339197..1b10e8319f1 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/config/ResourceHandlerRegistryTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/config/ResourceHandlerRegistryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 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. @@ -43,6 +43,8 @@ import org.springframework.web.reactive.resource.CssLinkResourceTransformer; import org.springframework.web.reactive.resource.PathResourceResolver; import org.springframework.web.reactive.resource.ResourceResolver; import org.springframework.web.reactive.resource.ResourceTransformer; +import org.springframework.web.reactive.resource.ResourceTransformerSupport; +import org.springframework.web.reactive.resource.ResourceUrlProvider; import org.springframework.web.reactive.resource.ResourceWebHandler; import org.springframework.web.reactive.resource.VersionResourceResolver; import org.springframework.web.reactive.resource.WebJarsResourceResolver; @@ -120,8 +122,11 @@ public class ResourceHandlerRegistryTests { @Test public void resourceChain() throws Exception { + ResourceUrlProvider resourceUrlProvider = Mockito.mock(ResourceUrlProvider.class); + this.registry.setResourceUrlProvider(resourceUrlProvider); ResourceResolver mockResolver = Mockito.mock(ResourceResolver.class); - ResourceTransformer mockTransformer = Mockito.mock(ResourceTransformer.class); + ResourceTransformerSupport mockTransformer = Mockito.mock(ResourceTransformerSupport.class); + this.registration.resourceChain(true).addResolver(mockResolver).addTransformer(mockTransformer); ResourceWebHandler handler = getHandler("/resources/**"); @@ -138,6 +143,7 @@ public class ResourceHandlerRegistryTests { assertThat(transformers, Matchers.hasSize(2)); assertThat(transformers.get(0), Matchers.instanceOf(CachingResourceTransformer.class)); assertThat(transformers.get(1), Matchers.equalTo(mockTransformer)); + Mockito.verify(mockTransformer).setResourceUrlProvider(resourceUrlProvider); } @Test diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/config/WebFluxConfigurationSupportTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/config/WebFluxConfigurationSupportTests.java index 108e92d516a..abc8a9a64bc 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/config/WebFluxConfigurationSupportTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/config/WebFluxConfigurationSupportTests.java @@ -60,6 +60,7 @@ import org.springframework.web.method.HandlerTypePredicate; import org.springframework.web.reactive.accept.RequestedContentTypeResolver; import org.springframework.web.reactive.handler.AbstractUrlHandlerMapping; import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping; +import org.springframework.web.reactive.resource.ResourceUrlProvider; import org.springframework.web.reactive.result.method.RequestMappingInfo; import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter; import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping; @@ -285,6 +286,15 @@ public class WebFluxConfigurationSupportTests { assertNotNull(webHandler); } + @Test + public void resourceUrlProvider() throws Exception { + ApplicationContext context = loadConfig(WebFluxConfig.class); + + String name = "resourceUrlProvider"; + ResourceUrlProvider resourceUrlProvider = context.getBean(name, ResourceUrlProvider.class); + assertNotNull(resourceUrlProvider); + } + private void assertHasMessageReader(List> readers, ResolvableType type, MediaType mediaType) { assertTrue(readers.stream().anyMatch(c -> mediaType == null || c.canRead(type, mediaType)));