Skip to content

Commit 9e5f171

Browse files
ayudovinbclozel
authored andcommitted
Support cachecontrol config property in WebFlux
Closes gh-14724
1 parent 66af20f commit 9e5f171

File tree

2 files changed

+61
-8
lines changed

2 files changed

+61
-8
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfiguration.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
import java.time.Duration;
2020
import java.util.Collection;
21-
import java.util.concurrent.TimeUnit;
2221

2322
import org.apache.commons.logging.Log;
2423
import org.apache.commons.logging.LogFactory;
@@ -50,7 +49,6 @@
5049
import org.springframework.format.Formatter;
5150
import org.springframework.format.FormatterRegistry;
5251
import org.springframework.format.support.FormattingConversionService;
53-
import org.springframework.http.CacheControl;
5452
import org.springframework.http.codec.ServerCodecConfigurer;
5553
import org.springframework.util.ClassUtils;
5654
import org.springframework.validation.Validator;
@@ -151,25 +149,27 @@ public void addResourceHandlers(ResourceHandlerRegistry registry) {
151149
return;
152150
}
153151
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
152+
ResourceProperties.Cache.Cachecontrol cacheControl = this.resourceProperties
153+
.getCache().getCachecontrol();
154154
if (!registry.hasMappingForPattern("/webjars/**")) {
155155
ResourceHandlerRegistration registration = registry
156156
.addResourceHandler("/webjars/**")
157157
.addResourceLocations("classpath:/META-INF/resources/webjars/");
158-
if (cachePeriod != null) {
159-
registration.setCacheControl(CacheControl
160-
.maxAge(cachePeriod.toMillis(), TimeUnit.MILLISECONDS));
158+
if (cachePeriod != null && cacheControl.getMaxAge() == null) {
159+
cacheControl.setMaxAge(cachePeriod);
161160
}
161+
registration.setCacheControl(cacheControl.toHttpCacheControl());
162162
customizeResourceHandlerRegistration(registration);
163163
}
164164
String staticPathPattern = this.webFluxProperties.getStaticPathPattern();
165165
if (!registry.hasMappingForPattern(staticPathPattern)) {
166166
ResourceHandlerRegistration registration = registry
167167
.addResourceHandler(staticPathPattern).addResourceLocations(
168168
this.resourceProperties.getStaticLocations());
169-
if (cachePeriod != null) {
170-
registration.setCacheControl(CacheControl
171-
.maxAge(cachePeriod.toMillis(), TimeUnit.MILLISECONDS));
169+
if (cachePeriod != null && cacheControl.getMaxAge() == null) {
170+
cacheControl.setMaxAge(cachePeriod);
172171
}
172+
registration.setCacheControl(cacheControl.toHttpCacheControl());
173173
customizeResourceHandlerRegistration(registration);
174174
}
175175
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/WebFluxAutoConfigurationTests.java

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616

1717
package org.springframework.boot.autoconfigure.web.reactive;
1818

19+
import java.util.Collections;
1920
import java.util.Date;
2021
import java.util.List;
22+
import java.util.Map;
23+
import java.util.concurrent.TimeUnit;
2124

2225
import javax.validation.ValidatorFactory;
2326

@@ -28,6 +31,7 @@
2831
import org.springframework.boot.autoconfigure.AutoConfigurations;
2932
import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration;
3033
import org.springframework.boot.autoconfigure.validation.ValidatorAdapter;
34+
import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext;
3135
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
3236
import org.springframework.boot.web.codec.CodecCustomizer;
3337
import org.springframework.boot.web.reactive.filter.OrderedHiddenHttpMethodFilter;
@@ -38,6 +42,7 @@
3842
import org.springframework.core.annotation.Order;
3943
import org.springframework.core.io.ClassPathResource;
4044
import org.springframework.format.support.FormattingConversionService;
45+
import org.springframework.http.CacheControl;
4146
import org.springframework.http.codec.ServerCodecConfigurer;
4247
import org.springframework.http.server.reactive.HttpHandler;
4348
import org.springframework.test.util.ReflectionTestUtils;
@@ -58,6 +63,7 @@
5863
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;
5964
import org.springframework.web.reactive.result.view.ViewResolutionResultHandler;
6065
import org.springframework.web.reactive.result.view.ViewResolver;
66+
import org.springframework.web.util.pattern.PathPattern;
6167

6268
import static org.assertj.core.api.Assertions.assertThat;
6369
import static org.mockito.ArgumentMatchers.any;
@@ -406,6 +412,53 @@ public void multipleWebFluxRegistrations() {
406412
});
407413
}
408414

415+
@Test
416+
public void cachePeriod() {
417+
this.contextRunner.withPropertyValues("spring.resources.cache.period:5")
418+
.run(this::assertCachePeriod);
419+
}
420+
421+
@Test
422+
public void cacheControl() {
423+
this.contextRunner
424+
.withPropertyValues("spring.resources.cache.cachecontrol.max-age:5",
425+
"spring.resources.cache.cachecontrol.proxy-revalidate:true")
426+
.run(this::assertCacheControl);
427+
}
428+
429+
private void assertCachePeriod(AssertableReactiveWebApplicationContext context) {
430+
Map<PathPattern, Object> handlerMap = getHandlerMap(
431+
context.getBean("resourceHandlerMapping", HandlerMapping.class));
432+
assertThat(handlerMap).hasSize(2);
433+
for (Object handler : handlerMap.values()) {
434+
if (handler instanceof ResourceWebHandler) {
435+
assertThat(((ResourceWebHandler) handler).getCacheControl())
436+
.isEqualToComparingFieldByField(
437+
CacheControl.maxAge(5, TimeUnit.SECONDS));
438+
}
439+
}
440+
}
441+
442+
private Map<PathPattern, Object> getHandlerMap(HandlerMapping mapping) {
443+
if (mapping instanceof SimpleUrlHandlerMapping) {
444+
return ((SimpleUrlHandlerMapping) mapping).getHandlerMap();
445+
}
446+
return Collections.emptyMap();
447+
}
448+
449+
private void assertCacheControl(AssertableReactiveWebApplicationContext context) {
450+
Map<PathPattern, Object> handlerMap = getHandlerMap(
451+
context.getBean("resourceHandlerMapping", HandlerMapping.class));
452+
assertThat(handlerMap).hasSize(2);
453+
for (Object handler : handlerMap.values()) {
454+
if (handler instanceof ResourceWebHandler) {
455+
assertThat(((ResourceWebHandler) handler).getCacheControl())
456+
.isEqualToComparingFieldByField(CacheControl
457+
.maxAge(5, TimeUnit.SECONDS).proxyRevalidate());
458+
}
459+
}
460+
}
461+
409462
@Configuration
410463
protected static class CustomArgumentResolvers {
411464

0 commit comments

Comments
 (0)