Skip to content

Commit 2d14bd7

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 (Cherry-picked from fc957e9)
1 parent 2acfb2e commit 2d14bd7

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
@@ -53,6 +53,7 @@
5353
import org.springframework.web.reactive.function.server.support.ServerResponseResultHandler;
5454
import org.springframework.web.reactive.handler.AbstractHandlerMapping;
5555
import org.springframework.web.reactive.handler.WebFluxResponseStatusExceptionHandler;
56+
import org.springframework.web.reactive.resource.ResourceUrlProvider;
5657
import org.springframework.web.reactive.result.SimpleHandlerAdapter;
5758
import org.springframework.web.reactive.result.method.annotation.ArgumentResolverConfigurer;
5859
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter;
@@ -72,6 +73,7 @@
7273
* <p>Import directly or extend and override protected methods to customize.
7374
*
7475
* @author Rossen Stoyanchev
76+
* @author Brian Clozel
7577
* @since 5.0
7678
*/
7779
public class WebFluxConfigurationSupport implements ApplicationContextAware {
@@ -218,6 +220,7 @@ public HandlerMapping resourceHandlerMapping() {
218220
resourceLoader = new DefaultResourceLoader();
219221
}
220222
ResourceHandlerRegistry registry = new ResourceHandlerRegistry(resourceLoader);
223+
registry.setResourceUrlProvider(resourceUrlProvider());
221224
addResourceHandlers(registry);
222225

223226
AbstractHandlerMapping handlerMapping = registry.getHandlerMapping();
@@ -238,6 +241,11 @@ public HandlerMapping resourceHandlerMapping() {
238241
return handlerMapping;
239242
}
240243

244+
@Bean
245+
public ResourceUrlProvider resourceUrlProvider() {
246+
return new ResourceUrlProvider();
247+
}
248+
241249
/**
242250
* Override this method to add resource handlers for serving static resources.
243251
* @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
@@ -52,6 +52,7 @@
5252
import org.springframework.web.reactive.accept.RequestedContentTypeResolver;
5353
import org.springframework.web.reactive.handler.AbstractUrlHandlerMapping;
5454
import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping;
55+
import org.springframework.web.reactive.resource.ResourceUrlProvider;
5556
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter;
5657
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;
5758
import org.springframework.web.reactive.result.method.annotation.ResponseBodyResultHandler;
@@ -267,6 +268,15 @@ public void resourceHandler() throws Exception {
267268
assertNotNull(webHandler);
268269
}
269270

271+
@Test
272+
public void resourceUrlProvider() throws Exception {
273+
ApplicationContext context = loadConfig(WebFluxConfig.class);
274+
275+
String name = "resourceUrlProvider";
276+
ResourceUrlProvider resourceUrlProvider = context.getBean(name, ResourceUrlProvider.class);
277+
assertNotNull(resourceUrlProvider);
278+
}
279+
270280

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

0 commit comments

Comments
 (0)