Skip to content

Commit fc957e9

Browse files
committed
Configure ResourceUrlProvider in WebFlux
Prior to this commit, no `ResourceUrlProvider` was configured in WebFlux (no bean was contributed by the WebFlux infrastructure). Also, several `ResourceTransformer` instances that extend the `ResourceTransformerSupport` base class need a `ResourceUrlProvider` to resolve absolute URLs when rewriting resource URLs. At this point, no `ResourceUrlProvider` was configured and they could only resolve relative URLs. This commit contributes a new `ResourceUrlProvider` to the WebFlux configuration; this bean can be reused by the WebFlux infrastructure and application code. This also automatically configure this shared `ResourceUrlProvider` instance on the resource chain where needed. Issue: SPR-17433
1 parent 3fee8cb commit fc957e9

File tree

4 files changed

+49
-3
lines changed

4 files changed

+49
-3
lines changed

spring-webflux/src/main/java/org/springframework/web/reactive/config/ResourceHandlerRegistry.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import org.springframework.lang.Nullable;
2929
import org.springframework.web.reactive.handler.AbstractUrlHandlerMapping;
3030
import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping;
31+
import org.springframework.web.reactive.resource.ResourceTransformerSupport;
32+
import org.springframework.web.reactive.resource.ResourceUrlProvider;
3133
import org.springframework.web.reactive.resource.ResourceWebHandler;
3234
import org.springframework.web.server.WebHandler;
3335

@@ -49,6 +51,7 @@
4951
* period for served resources.
5052
*
5153
* @author Rossen Stoyanchev
54+
* @author Brian Clozel
5255
* @since 5.0
5356
*/
5457
public class ResourceHandlerRegistry {
@@ -57,7 +60,10 @@ public class ResourceHandlerRegistry {
5760

5861
private final List<ResourceHandlerRegistration> registrations = new ArrayList<>();
5962

60-
private int order = Ordered.LOWEST_PRECEDENCE -1;
63+
private int order = Ordered.LOWEST_PRECEDENCE - 1;
64+
65+
@Nullable
66+
private ResourceUrlProvider resourceUrlProvider;
6167

6268

6369
/**
@@ -69,6 +75,17 @@ public ResourceHandlerRegistry(ResourceLoader resourceLoader) {
6975
this.resourceLoader = resourceLoader;
7076
}
7177

78+
/**
79+
* Configure the {@link ResourceUrlProvider} that can be used by
80+
* {@link org.springframework.web.reactive.resource.ResourceTransformer} instances.
81+
* @param resourceUrlProvider the resource URL provider to use
82+
* @since 5.1.2
83+
*/
84+
public void setResourceUrlProvider(@Nullable ResourceUrlProvider resourceUrlProvider) {
85+
this.resourceUrlProvider = resourceUrlProvider;
86+
}
87+
88+
7289

7390
/**
7491
* Add a resource handler for serving static resources based on the specified
@@ -121,6 +138,11 @@ protected AbstractUrlHandlerMapping getHandlerMapping() {
121138
for (ResourceHandlerRegistration registration : this.registrations) {
122139
for (String pathPattern : registration.getPathPatterns()) {
123140
ResourceWebHandler handler = registration.getRequestHandler();
141+
handler.getResourceTransformers().forEach(transformer -> {
142+
if (transformer instanceof ResourceTransformerSupport) {
143+
((ResourceTransformerSupport) transformer).setResourceUrlProvider(this.resourceUrlProvider);
144+
}
145+
});
124146
try {
125147
handler.afterPropertiesSet();
126148
}

spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurationSupport.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import org.springframework.web.reactive.function.server.support.ServerResponseResultHandler;
5656
import org.springframework.web.reactive.handler.AbstractHandlerMapping;
5757
import org.springframework.web.reactive.handler.WebFluxResponseStatusExceptionHandler;
58+
import org.springframework.web.reactive.resource.ResourceUrlProvider;
5859
import org.springframework.web.reactive.result.SimpleHandlerAdapter;
5960
import org.springframework.web.reactive.result.method.annotation.ArgumentResolverConfigurer;
6061
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter;
@@ -74,6 +75,7 @@
7475
* <p>Import directly or extend and override protected methods to customize.
7576
*
7677
* @author Rossen Stoyanchev
78+
* @author Brian Clozel
7779
* @since 5.0
7880
*/
7981
public class WebFluxConfigurationSupport implements ApplicationContextAware {
@@ -229,6 +231,7 @@ public HandlerMapping resourceHandlerMapping() {
229231
resourceLoader = new DefaultResourceLoader();
230232
}
231233
ResourceHandlerRegistry registry = new ResourceHandlerRegistry(resourceLoader);
234+
registry.setResourceUrlProvider(resourceUrlProvider());
232235
addResourceHandlers(registry);
233236

234237
AbstractHandlerMapping handlerMapping = registry.getHandlerMapping();
@@ -249,6 +252,11 @@ public HandlerMapping resourceHandlerMapping() {
249252
return handlerMapping;
250253
}
251254

255+
@Bean
256+
public ResourceUrlProvider resourceUrlProvider() {
257+
return new ResourceUrlProvider();
258+
}
259+
252260
/**
253261
* Override this method to add resource handlers for serving static resources.
254262
* @see ResourceHandlerRegistry

spring-webflux/src/test/java/org/springframework/web/reactive/config/ResourceHandlerRegistryTests.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -43,6 +43,8 @@
4343
import org.springframework.web.reactive.resource.PathResourceResolver;
4444
import org.springframework.web.reactive.resource.ResourceResolver;
4545
import org.springframework.web.reactive.resource.ResourceTransformer;
46+
import org.springframework.web.reactive.resource.ResourceTransformerSupport;
47+
import org.springframework.web.reactive.resource.ResourceUrlProvider;
4648
import org.springframework.web.reactive.resource.ResourceWebHandler;
4749
import org.springframework.web.reactive.resource.VersionResourceResolver;
4850
import org.springframework.web.reactive.resource.WebJarsResourceResolver;
@@ -120,8 +122,11 @@ public void hasMappingForPattern() {
120122

121123
@Test
122124
public void resourceChain() throws Exception {
125+
ResourceUrlProvider resourceUrlProvider = Mockito.mock(ResourceUrlProvider.class);
126+
this.registry.setResourceUrlProvider(resourceUrlProvider);
123127
ResourceResolver mockResolver = Mockito.mock(ResourceResolver.class);
124-
ResourceTransformer mockTransformer = Mockito.mock(ResourceTransformer.class);
128+
ResourceTransformerSupport mockTransformer = Mockito.mock(ResourceTransformerSupport.class);
129+
125130
this.registration.resourceChain(true).addResolver(mockResolver).addTransformer(mockTransformer);
126131

127132
ResourceWebHandler handler = getHandler("/resources/**");
@@ -138,6 +143,7 @@ public void resourceChain() throws Exception {
138143
assertThat(transformers, Matchers.hasSize(2));
139144
assertThat(transformers.get(0), Matchers.instanceOf(CachingResourceTransformer.class));
140145
assertThat(transformers.get(1), Matchers.equalTo(mockTransformer));
146+
Mockito.verify(mockTransformer).setResourceUrlProvider(resourceUrlProvider);
141147
}
142148

143149
@Test

spring-webflux/src/test/java/org/springframework/web/reactive/config/WebFluxConfigurationSupportTests.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import org.springframework.web.reactive.accept.RequestedContentTypeResolver;
6161
import org.springframework.web.reactive.handler.AbstractUrlHandlerMapping;
6262
import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping;
63+
import org.springframework.web.reactive.resource.ResourceUrlProvider;
6364
import org.springframework.web.reactive.result.method.RequestMappingInfo;
6465
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter;
6566
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;
@@ -285,6 +286,15 @@ public void resourceHandler() throws Exception {
285286
assertNotNull(webHandler);
286287
}
287288

289+
@Test
290+
public void resourceUrlProvider() throws Exception {
291+
ApplicationContext context = loadConfig(WebFluxConfig.class);
292+
293+
String name = "resourceUrlProvider";
294+
ResourceUrlProvider resourceUrlProvider = context.getBean(name, ResourceUrlProvider.class);
295+
assertNotNull(resourceUrlProvider);
296+
}
297+
288298

289299
private void assertHasMessageReader(List<HttpMessageReader<?>> readers, ResolvableType type, MediaType mediaType) {
290300
assertTrue(readers.stream().anyMatch(c -> mediaType == null || c.canRead(type, mediaType)));

0 commit comments

Comments
 (0)