Browse Source

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 fc957e95bb)
pull/2028/head
Brian Clozel 7 years ago
parent
commit
2d14bd7066
  1. 24
      spring-webflux/src/main/java/org/springframework/web/reactive/config/ResourceHandlerRegistry.java
  2. 8
      spring-webflux/src/main/java/org/springframework/web/reactive/config/WebFluxConfigurationSupport.java
  3. 10
      spring-webflux/src/test/java/org/springframework/web/reactive/config/ResourceHandlerRegistryTests.java
  4. 10
      spring-webflux/src/test/java/org/springframework/web/reactive/config/WebFluxConfigurationSupportTests.java

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

@ -28,6 +28,8 @@ import org.springframework.core.io.ResourceLoader; @@ -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; @@ -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 { @@ -57,7 +60,10 @@ public class ResourceHandlerRegistry {
private final List<ResourceHandlerRegistration> 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 { @@ -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 { @@ -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();
}

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

@ -53,6 +53,7 @@ import org.springframework.web.reactive.function.server.support.RouterFunctionMa @@ -53,6 +53,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;
@ -72,6 +73,7 @@ import org.springframework.web.server.i18n.LocaleContextResolver; @@ -72,6 +73,7 @@ import org.springframework.web.server.i18n.LocaleContextResolver;
* <p>Import directly or extend and override protected methods to customize.
*
* @author Rossen Stoyanchev
* @author Brian Clozel
* @since 5.0
*/
public class WebFluxConfigurationSupport implements ApplicationContextAware {
@ -218,6 +220,7 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware { @@ -218,6 +220,7 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware {
resourceLoader = new DefaultResourceLoader();
}
ResourceHandlerRegistry registry = new ResourceHandlerRegistry(resourceLoader);
registry.setResourceUrlProvider(resourceUrlProvider());
addResourceHandlers(registry);
AbstractHandlerMapping handlerMapping = registry.getHandlerMapping();
@ -238,6 +241,11 @@ public class WebFluxConfigurationSupport implements ApplicationContextAware { @@ -238,6 +241,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

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

@ -1,5 +1,5 @@ @@ -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; @@ -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 { @@ -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 { @@ -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

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

@ -52,6 +52,7 @@ import org.springframework.web.bind.support.WebExchangeDataBinder; @@ -52,6 +52,7 @@ import org.springframework.web.bind.support.WebExchangeDataBinder;
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.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.reactive.result.method.annotation.ResponseBodyResultHandler;
@ -267,6 +268,15 @@ public class WebFluxConfigurationSupportTests { @@ -267,6 +268,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<HttpMessageReader<?>> readers, ResolvableType type, MediaType mediaType) {
assertTrue(readers.stream().anyMatch(c -> mediaType == null || c.canRead(type, mediaType)));

Loading…
Cancel
Save