Support EncodedResourceResolver in resource chain

As of https://jira.spring.io/browse/SPR-16381, Spring Framework now
supports both gzip and Brotli as compression formats for static
resources resolved by the resource chain.

The `GzipResourceResolver` has been deprecated and replaced by the
`EncodedResourceResolver`. This commit uses this new resolver and adapts
the configuration key to reflect those changes.

Note that this resolver is now configured ahead of the
`VersionResourceResolver`.

Closes gh-13242
pull/13377/head
Brian Clozel 7 years ago
parent ace5ba5984
commit 56ab0da287

@ -112,10 +112,10 @@ public class ResourceProperties {
private boolean htmlApplicationCache = false; private boolean htmlApplicationCache = false;
/** /**
* Whether to enable resolution of already gzipped resources. Checks for a * Whether to enable resolution of already compressed resources. Checks for a
* resource name variant with the "*.gz" extension. * resource name with the '.gz' or '.br' file extensions.
*/ */
private boolean gzipped = false; private boolean compressed = false;
private final Strategy strategy = new Strategy(); private final Strategy strategy = new Strategy();
@ -154,12 +154,12 @@ public class ResourceProperties {
this.htmlApplicationCache = htmlApplicationCache; this.htmlApplicationCache = htmlApplicationCache;
} }
public boolean isGzipped() { public boolean isCompressed() {
return this.gzipped; return this.compressed;
} }
public void setGzipped(boolean gzipped) { public void setCompressed(boolean compressed) {
this.gzipped = gzipped; this.compressed = compressed;
} }
static Boolean getEnabled(boolean fixedEnabled, boolean contentEnabled, static Boolean getEnabled(boolean fixedEnabled, boolean contentEnabled,

@ -64,7 +64,7 @@ import org.springframework.web.reactive.config.ViewResolverRegistry;
import org.springframework.web.reactive.config.WebFluxConfigurationSupport; import org.springframework.web.reactive.config.WebFluxConfigurationSupport;
import org.springframework.web.reactive.config.WebFluxConfigurer; import org.springframework.web.reactive.config.WebFluxConfigurer;
import org.springframework.web.reactive.resource.AppCacheManifestTransformer; import org.springframework.web.reactive.resource.AppCacheManifestTransformer;
import org.springframework.web.reactive.resource.GzipResourceResolver; import org.springframework.web.reactive.resource.EncodedResourceResolver;
import org.springframework.web.reactive.resource.ResourceResolver; import org.springframework.web.reactive.resource.ResourceResolver;
import org.springframework.web.reactive.resource.VersionResourceResolver; import org.springframework.web.reactive.resource.VersionResourceResolver;
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver; import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver;
@ -275,12 +275,12 @@ public class WebFluxAutoConfiguration {
private void configureResourceChain(ResourceProperties.Chain properties, private void configureResourceChain(ResourceProperties.Chain properties,
ResourceChainRegistration chain) { ResourceChainRegistration chain) {
ResourceProperties.Strategy strategy = properties.getStrategy(); ResourceProperties.Strategy strategy = properties.getStrategy();
if (properties.isCompressed()) {
chain.addResolver(new EncodedResourceResolver());
}
if (strategy.getFixed().isEnabled() || strategy.getContent().isEnabled()) { if (strategy.getFixed().isEnabled() || strategy.getContent().isEnabled()) {
chain.addResolver(getVersionResourceResolver(strategy)); chain.addResolver(getVersionResourceResolver(strategy));
} }
if (properties.isGzipped()) {
chain.addResolver(new GzipResourceResolver());
}
if (properties.isHtmlApplicationCache()) { if (properties.isHtmlApplicationCache()) {
chain.addTransformer(new AppCacheManifestTransformer()); chain.addTransformer(new AppCacheManifestTransformer());
} }

@ -115,7 +115,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExc
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.servlet.resource.AppCacheManifestTransformer; import org.springframework.web.servlet.resource.AppCacheManifestTransformer;
import org.springframework.web.servlet.resource.GzipResourceResolver; import org.springframework.web.servlet.resource.EncodedResourceResolver;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
import org.springframework.web.servlet.resource.ResourceResolver; import org.springframework.web.servlet.resource.ResourceResolver;
import org.springframework.web.servlet.resource.VersionResourceResolver; import org.springframework.web.servlet.resource.VersionResourceResolver;
@ -602,12 +602,12 @@ public class WebMvcAutoConfiguration {
private void configureResourceChain(ResourceProperties.Chain properties, private void configureResourceChain(ResourceProperties.Chain properties,
ResourceChainRegistration chain) { ResourceChainRegistration chain) {
Strategy strategy = properties.getStrategy(); Strategy strategy = properties.getStrategy();
if (properties.isCompressed()) {
chain.addResolver(new EncodedResourceResolver());
}
if (strategy.getFixed().isEnabled() || strategy.getContent().isEnabled()) { if (strategy.getFixed().isEnabled() || strategy.getContent().isEnabled()) {
chain.addResolver(getVersionResourceResolver(strategy)); chain.addResolver(getVersionResourceResolver(strategy));
} }
if (properties.isGzipped()) {
chain.addResolver(new GzipResourceResolver());
}
if (properties.isHtmlApplicationCache()) { if (properties.isHtmlApplicationCache()) {
chain.addTransformer(new AppCacheManifestTransformer()); chain.addTransformer(new AppCacheManifestTransformer());
} }

@ -455,6 +455,15 @@
"name": "spring.mvc.locale-resolver", "name": "spring.mvc.locale-resolver",
"defaultValue": "accept-header" "defaultValue": "accept-header"
}, },
{
"name" : "spring.resources.chain.gzipped",
"type" : "java.lang.Boolean",
"description" : "Whether to enable resolution of already gzipped resources. Checks for a resource name variant with the \"*.gz\" extension.",
"deprecation" : {
"replacement" : "spring.resources.chain.compressed",
"level" : "error"
}
},
{ {
"name": "spring.quartz.jdbc.initialize-schema", "name": "spring.quartz.jdbc.initialize-schema",
"defaultValue": "embedded" "defaultValue": "embedded"

@ -90,8 +90,8 @@ import org.springframework.web.servlet.resource.CachingResourceResolver;
import org.springframework.web.servlet.resource.CachingResourceTransformer; import org.springframework.web.servlet.resource.CachingResourceTransformer;
import org.springframework.web.servlet.resource.ContentVersionStrategy; import org.springframework.web.servlet.resource.ContentVersionStrategy;
import org.springframework.web.servlet.resource.CssLinkResourceTransformer; import org.springframework.web.servlet.resource.CssLinkResourceTransformer;
import org.springframework.web.servlet.resource.EncodedResourceResolver;
import org.springframework.web.servlet.resource.FixedVersionStrategy; import org.springframework.web.servlet.resource.FixedVersionStrategy;
import org.springframework.web.servlet.resource.GzipResourceResolver;
import org.springframework.web.servlet.resource.PathResourceResolver; import org.springframework.web.servlet.resource.PathResourceResolver;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
import org.springframework.web.servlet.resource.ResourceResolver; import org.springframework.web.servlet.resource.ResourceResolver;
@ -276,21 +276,21 @@ public class WebMvcAutoConfigurationTests {
"spring.resources.chain.strategy.fixed.version:test", "spring.resources.chain.strategy.fixed.version:test",
"spring.resources.chain.strategy.fixed.paths:/**/*.js", "spring.resources.chain.strategy.fixed.paths:/**/*.js",
"spring.resources.chain.html-application-cache:true", "spring.resources.chain.html-application-cache:true",
"spring.resources.chain.gzipped:true").run((context) -> { "spring.resources.chain.compressed:true").run((context) -> {
assertThat(getResourceResolvers(context, "/webjars/**")).hasSize(3); assertThat(getResourceResolvers(context, "/webjars/**")).hasSize(3);
assertThat(getResourceTransformers(context, "/webjars/**")) assertThat(getResourceTransformers(context, "/webjars/**"))
.hasSize(2); .hasSize(2);
assertThat(getResourceResolvers(context, "/**")) assertThat(getResourceResolvers(context, "/**"))
.extractingResultOf("getClass") .extractingResultOf("getClass")
.containsOnly(VersionResourceResolver.class, .containsOnly(EncodedResourceResolver.class,
GzipResourceResolver.class, VersionResourceResolver.class,
PathResourceResolver.class); PathResourceResolver.class);
assertThat(getResourceTransformers(context, "/**")) assertThat(getResourceTransformers(context, "/**"))
.extractingResultOf("getClass") .extractingResultOf("getClass")
.containsOnly(CssLinkResourceTransformer.class, .containsOnly(CssLinkResourceTransformer.class,
AppCacheManifestTransformer.class); AppCacheManifestTransformer.class);
VersionResourceResolver resolver = (VersionResourceResolver) getResourceResolvers( VersionResourceResolver resolver = (VersionResourceResolver) getResourceResolvers(
context, "/**").get(0); context, "/**").get(1);
Map<String, VersionStrategy> strategyMap = resolver.getStrategyMap(); Map<String, VersionStrategy> strategyMap = resolver.getStrategyMap();
assertThat(strategyMap.get("/*.png")) assertThat(strategyMap.get("/*.png"))
.isInstanceOf(ContentVersionStrategy.class); .isInstanceOf(ContentVersionStrategy.class);

@ -435,8 +435,8 @@ content into your application. Rather, pick only the properties that you need.
spring.resources.cache.cachecontrol.stale-while-revalidate= # Maximum time the response can be served after it becomes stale, in seconds if no duration suffix is not specified. spring.resources.cache.cachecontrol.stale-while-revalidate= # Maximum time the response can be served after it becomes stale, in seconds if no duration suffix is not specified.
spring.resources.cache.period= # Cache period for the resources served by the resource handler. If a duration suffix is not specified, seconds will be used. spring.resources.cache.period= # Cache period for the resources served by the resource handler. If a duration suffix is not specified, seconds will be used.
spring.resources.chain.cache=true # Whether to enable caching in the Resource chain. spring.resources.chain.cache=true # Whether to enable caching in the Resource chain.
spring.resources.chain.compressed=false # Whether to enable resolution of already compressed resources (gzip, brotli).
spring.resources.chain.enabled= # Whether to enable the Spring Resource Handling chain. By default, disabled unless at least one strategy has been enabled. spring.resources.chain.enabled= # Whether to enable the Spring Resource Handling chain. By default, disabled unless at least one strategy has been enabled.
spring.resources.chain.gzipped=false # Whether to enable resolution of already gzipped resources.
spring.resources.chain.html-application-cache=false # Whether to enable HTML5 application cache manifest rewriting. spring.resources.chain.html-application-cache=false # Whether to enable HTML5 application cache manifest rewriting.
spring.resources.chain.strategy.content.enabled=false # Whether to enable the content Version Strategy. spring.resources.chain.strategy.content.enabled=false # Whether to enable the content Version Strategy.
spring.resources.chain.strategy.content.paths=/** # Comma-separated list of patterns to apply to the content Version Strategy. spring.resources.chain.strategy.content.paths=/** # Comma-separated list of patterns to apply to the content Version Strategy.

Loading…
Cancel
Save