From 4ca04abcb28ae7fbea720a8dc27b2656b9a05756 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Wed, 17 Feb 2016 16:33:31 +0100 Subject: [PATCH 1/2] 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); From 888270bd036509a1e1564acd57393b94cff71de4 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Thu, 18 Feb 2016 11:30:02 +0100 Subject: [PATCH 2/2] Polish contribution Closes gh-5171 --- .../boot/autoconfigure/web/ResourceProperties.java | 1 + .../src/main/asciidoc/appendix-application-properties.adoc | 1 + 2 files changed, 2 insertions(+) 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 2838be1e34..ac51dba842 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 @@ -221,6 +221,7 @@ public class ResourceProperties implements ResourceLoaderAware { public void setGzipped(boolean gzipped) { this.gzipped = gzipped; } + } /** diff --git a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc index 923f5293db..fdd2689a6b 100644 --- a/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc +++ b/spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc @@ -322,6 +322,7 @@ content into your application; rather pick only the properties that you need. spring.resources.cache-period= # Cache period for the resources served by the resource handler, in seconds. spring.resources.chain.cache=true # Enable caching in the Resource chain. spring.resources.chain.enabled= # Enable the Spring Resource Handling chain. Disabled by default unless at least one strategy has been enabled. + spring.resources.chain.gzipped=false # Enable resolution of already gzipped resources. spring.resources.chain.html-application-cache=false # Enable HTML5 application cache manifest rewriting. spring.resources.chain.strategy.content.enabled=false # Enable the content Version Strategy. spring.resources.chain.strategy.content.paths=/** # Comma-separated list of patterns to apply to the Version Strategy.