From 4ca04abcb28ae7fbea720a8dc27b2656b9a05756 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Wed, 17 Feb 2016 16:33:31 +0100 Subject: [PATCH] Add configuration key for GzipResourceResolver This commit adds a new key that configures a GzipResourceResolver in the resource handling chain. Configuring an application with the following will add that resolver, which checks for gzipped resources in the configured locations: ``` spring.resources.chain.gzipped=true ``` This means that if a resource "style.css" is requested, the GzipResourceResolver will look for resources named "style.css.gz", which should be a gzipped variant of the "style.css" file. Note that this resolver only checks for variants if the client supports the "gzip" encoding, as defined in the "Accept-Encoding" HTTP request headers. Fixes #4683 --- .../boot/autoconfigure/web/ResourceProperties.java | 13 +++++++++++++ .../autoconfigure/web/WebMvcAutoConfiguration.java | 4 ++++ .../web/WebMvcAutoConfigurationTests.java | 9 ++++++--- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ResourceProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ResourceProperties.java index a86bcc0b73..2838be1e34 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ResourceProperties.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ResourceProperties.java @@ -169,6 +169,12 @@ public class ResourceProperties implements ResourceLoaderAware { */ private boolean htmlApplicationCache = false; + /** + * Enable resolution of already gzipped resources. Checks for a resource + * name variant with the *.gz extension. + */ + private boolean gzipped = false; + @NestedConfigurationProperty private final Strategy strategy = new Strategy(); @@ -208,6 +214,13 @@ public class ResourceProperties implements ResourceLoaderAware { this.htmlApplicationCache = htmlApplicationCache; } + public boolean isGzipped() { + return this.gzipped; + } + + public void setGzipped(boolean gzipped) { + this.gzipped = gzipped; + } } /** diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java index b70565a09c..133a01d98b 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java @@ -85,6 +85,7 @@ import org.springframework.web.servlet.i18n.FixedLocaleResolver; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import org.springframework.web.servlet.resource.AppCacheManifestTransformer; +import org.springframework.web.servlet.resource.GzipResourceResolver; import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; import org.springframework.web.servlet.resource.ResourceResolver; import org.springframework.web.servlet.resource.VersionResourceResolver; @@ -396,6 +397,9 @@ public class WebMvcAutoConfiguration { if (strategy.getFixed().isEnabled() || strategy.getContent().isEnabled()) { chain.addResolver(getVersionResourceResolver(strategy)); } + if (properties.isGzipped()) { + chain.addResolver(new GzipResourceResolver()); + } if (properties.isHtmlApplicationCache()) { chain.addTransformer(new AppCacheManifestTransformer()); } diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfigurationTests.java index d378e77ce3..9436de6553 100644 --- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfigurationTests.java +++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfigurationTests.java @@ -71,6 +71,7 @@ import org.springframework.web.servlet.resource.CachingResourceTransformer; import org.springframework.web.servlet.resource.ContentVersionStrategy; import org.springframework.web.servlet.resource.CssLinkResourceTransformer; 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.ResourceHttpRequestHandler; import org.springframework.web.servlet.resource.ResourceResolver; @@ -228,11 +229,13 @@ public class WebMvcAutoConfigurationTests { "spring.resources.chain.strategy.fixed.enabled:true", "spring.resources.chain.strategy.fixed.version:test", "spring.resources.chain.strategy.fixed.paths:/**/*.js", - "spring.resources.chain.html-application-cache:true"); - assertThat(getResourceResolvers("/webjars/**")).hasSize(2); + "spring.resources.chain.html-application-cache:true", + "spring.resources.chain.gzipped:true"); + assertThat(getResourceResolvers("/webjars/**")).hasSize(3); assertThat(getResourceTransformers("/webjars/**")).hasSize(2); assertThat(getResourceResolvers("/**")).extractingResultOf("getClass") - .containsOnly(VersionResourceResolver.class, PathResourceResolver.class); + .containsOnly(VersionResourceResolver.class, GzipResourceResolver.class, + PathResourceResolver.class); assertThat(getResourceTransformers("/**")).extractingResultOf("getClass") .containsOnly(CssLinkResourceTransformer.class, AppCacheManifestTransformer.class);