Commit a6ccb4a6 authored by Stephane Nicoll's avatar Stephane Nicoll

Polish

Polish resource handling chain support. Make sure that the chain is
enabled automatically if at least one strategy is enabled.

See gh-1604
parent dd561d15
...@@ -57,6 +57,7 @@ import com.github.mxab.thymeleaf.extras.dataattribute.dialect.DataAttributeDiale ...@@ -57,6 +57,7 @@ import com.github.mxab.thymeleaf.extras.dataattribute.dialect.DataAttributeDiale
* @author Dave Syer * @author Dave Syer
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Stephane Nicoll * @author Stephane Nicoll
* @author Brian Clozel
*/ */
@Configuration @Configuration
@EnableConfigurationProperties(ThymeleafProperties.class) @EnableConfigurationProperties(ThymeleafProperties.class)
......
...@@ -51,6 +51,7 @@ import org.springframework.web.servlet.view.velocity.VelocityViewResolver; ...@@ -51,6 +51,7 @@ import org.springframework.web.servlet.view.velocity.VelocityViewResolver;
* {@link EnableAutoConfiguration Auto-configuration} for Velocity. * {@link EnableAutoConfiguration Auto-configuration} for Velocity.
* *
* @author Andy Wilkinson * @author Andy Wilkinson
* @author Brian Clozel
* @since 1.1.0 * @since 1.1.0
*/ */
@Configuration @Configuration
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
package org.springframework.boot.autoconfigure.web; package org.springframework.boot.autoconfigure.web;
import javax.annotation.PostConstruct;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
/** /**
...@@ -40,6 +42,15 @@ public class ResourceProperties { ...@@ -40,6 +42,15 @@ public class ResourceProperties {
private final Chain chain = new Chain(); private final Chain chain = new Chain();
@PostConstruct
public void setUpDefaults() {
if (this.chain.enabled == null && (this.chain.strategy.content.enabled
|| this.chain.strategy.fixed.enabled)) {
this.chain.enabled = true;
}
}
public Integer getCachePeriod() { public Integer getCachePeriod() {
return this.cachePeriod; return this.cachePeriod;
} }
...@@ -66,9 +77,10 @@ public class ResourceProperties { ...@@ -66,9 +77,10 @@ public class ResourceProperties {
public static class Chain { public static class Chain {
/** /**
* Enable the Spring Resource Handling chain. * Enable the Spring Resource Handling chain. Disabled by default unless
* at least one strategy has been enabled.
*/ */
private boolean enabled = false; private Boolean enabled;
/** /**
* Enable caching in the Resource chain. * Enable caching in the Resource chain.
...@@ -80,9 +92,9 @@ public class ResourceProperties { ...@@ -80,9 +92,9 @@ public class ResourceProperties {
*/ */
private boolean html5AppCache = false; private boolean html5AppCache = false;
private Strategy strategy = new Strategy(); private final Strategy strategy = new Strategy();
public boolean isEnabled() { public Boolean getEnabled() {
return enabled; return enabled;
} }
...@@ -116,9 +128,9 @@ public class ResourceProperties { ...@@ -116,9 +128,9 @@ public class ResourceProperties {
*/ */
public static class Strategy { public static class Strategy {
private Fixed fixed = new Fixed(); private final Fixed fixed = new Fixed();
private Content content = new Content(); private final Content content = new Content();
public Fixed getFixed() { public Fixed getFixed() {
return fixed; return fixed;
...@@ -137,7 +149,7 @@ public class ResourceProperties { ...@@ -137,7 +149,7 @@ public class ResourceProperties {
/** /**
* Enable the content Version Strategy. * Enable the content Version Strategy.
*/ */
private boolean enabled = false; private boolean enabled;
/** /**
* Comma-separated list of patterns to apply to the Version Strategy. * Comma-separated list of patterns to apply to the Version Strategy.
...@@ -169,7 +181,7 @@ public class ResourceProperties { ...@@ -169,7 +181,7 @@ public class ResourceProperties {
/** /**
* Enable the fixed Version Strategy. * Enable the fixed Version Strategy.
*/ */
private boolean enabled = false; private boolean enabled;
/** /**
* Comma-separated list of patterns to apply to the Version Strategy. * Comma-separated list of patterns to apply to the Version Strategy.
......
...@@ -55,6 +55,7 @@ import org.springframework.format.Formatter; ...@@ -55,6 +55,7 @@ import org.springframework.format.Formatter;
import org.springframework.format.FormatterRegistry; import org.springframework.format.FormatterRegistry;
import org.springframework.format.datetime.DateFormatter; import org.springframework.format.datetime.DateFormatter;
import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.validation.DefaultMessageCodesResolver; import org.springframework.validation.DefaultMessageCodesResolver;
import org.springframework.validation.MessageCodesResolver; import org.springframework.validation.MessageCodesResolver;
...@@ -274,7 +275,7 @@ public class WebMvcAutoConfiguration { ...@@ -274,7 +275,7 @@ public class WebMvcAutoConfiguration {
private void registerResourceChain(ResourceHandlerRegistration registration) { private void registerResourceChain(ResourceHandlerRegistration registration) {
ResourceProperties.Chain chainProperties = this.resourceProperties.getChain(); ResourceProperties.Chain chainProperties = this.resourceProperties.getChain();
if (chainProperties.isEnabled()) { if (ObjectUtils.nullSafeEquals(chainProperties.getEnabled(), Boolean.TRUE)) {
ResourceChainRegistration chain = registration.resourceChain(chainProperties.isCache()); ResourceChainRegistration chain = registration.resourceChain(chainProperties.isCache());
boolean hasFixedVersionConfigured = chainProperties.getStrategy().getFixed().isEnabled(); boolean hasFixedVersionConfigured = chainProperties.getStrategy().getFixed().isEnabled();
boolean hasContentVersionConfigured = chainProperties.getStrategy().getContent().isEnabled(); boolean hasContentVersionConfigured = chainProperties.getStrategy().getContent().isEnabled();
......
...@@ -169,12 +169,8 @@ public class WebMvcAutoConfigurationTests { ...@@ -169,12 +169,8 @@ public class WebMvcAutoConfigurationTests {
@Test @Test
public void resourceHandlerChainEnabled() throws Exception { public void resourceHandlerChainEnabled() throws Exception {
this.context = new AnnotationConfigEmbeddedWebApplicationContext(); load("spring.resources.chain.enabled:true");
EnvironmentTestUtils.addEnvironment(this.context, "spring.resources.chain.enabled:true");
this.context.register(Config.class, WebMvcAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
assertThat(getResourceResolvers("/webjars/**").size(), equalTo(2)); assertThat(getResourceResolvers("/webjars/**").size(), equalTo(2));
assertThat(getResourceTransformers("/webjars/**").size(), equalTo(1)); assertThat(getResourceTransformers("/webjars/**").size(), equalTo(1));
assertThat(getResourceResolvers("/**").size(), equalTo(2)); assertThat(getResourceResolvers("/**").size(), equalTo(2));
...@@ -185,21 +181,55 @@ public class WebMvcAutoConfigurationTests { ...@@ -185,21 +181,55 @@ public class WebMvcAutoConfigurationTests {
assertThat(getResourceTransformers("/**"), contains(instanceOf(CachingResourceTransformer.class))); assertThat(getResourceTransformers("/**"), contains(instanceOf(CachingResourceTransformer.class)));
} }
@Test
public void resourceHandlerFixedStrategyEnabled() throws Exception {
load("spring.resources.chain.strategy.fixed.enabled:true",
"spring.resources.chain.strategy.fixed.version:test",
"spring.resources.chain.strategy.fixed.paths:/**/*.js");
assertThat(getResourceResolvers("/webjars/**").size(), equalTo(3));
assertThat(getResourceTransformers("/webjars/**").size(), equalTo(2));
assertThat(getResourceResolvers("/**").size(), equalTo(3));
assertThat(getResourceTransformers("/**").size(), equalTo(2));
assertThat(getResourceResolvers("/**"), contains(instanceOf(CachingResourceResolver.class),
instanceOf(VersionResourceResolver.class),
instanceOf(PathResourceResolver.class)));
assertThat(getResourceTransformers("/**"), contains(instanceOf(CachingResourceTransformer.class),
instanceOf(CssLinkResourceTransformer.class)));
VersionResourceResolver resolver = (VersionResourceResolver) getResourceResolvers("/**").get(1);
assertThat(resolver.getStrategyMap().get("/**/*.js"), instanceOf(FixedVersionStrategy.class));
}
@Test
public void resourceHandlerContentStrategyEnabled() throws Exception {
load("spring.resources.chain.strategy.content.enabled:true",
"spring.resources.chain.strategy.content.paths:/**,/*.png");
assertThat(getResourceResolvers("/webjars/**").size(), equalTo(3));
assertThat(getResourceTransformers("/webjars/**").size(), equalTo(2));
assertThat(getResourceResolvers("/**").size(), equalTo(3));
assertThat(getResourceTransformers("/**").size(), equalTo(2));
assertThat(getResourceResolvers("/**"), contains(instanceOf(CachingResourceResolver.class),
instanceOf(VersionResourceResolver.class),
instanceOf(PathResourceResolver.class)));
assertThat(getResourceTransformers("/**"), contains(instanceOf(CachingResourceTransformer.class),
instanceOf(CssLinkResourceTransformer.class)));
VersionResourceResolver resolver = (VersionResourceResolver) getResourceResolvers("/**").get(1);
assertThat(resolver.getStrategyMap().get("/*.png"), instanceOf(ContentVersionStrategy.class));
}
@Test @Test
public void resourceHandlerChainCustomized() throws Exception { public void resourceHandlerChainCustomized() throws Exception {
this.context = new AnnotationConfigEmbeddedWebApplicationContext(); load("spring.resources.chain.enabled:true", "spring.resources.chain.cache:false",
EnvironmentTestUtils.addEnvironment(this.context,
"spring.resources.chain.enabled:true", "spring.resources.chain.cache:false",
"spring.resources.chain.strategy.content.enabled:true", "spring.resources.chain.strategy.content.enabled:true",
"spring.resources.chain.strategy.content.paths:/**,/*.png", "spring.resources.chain.strategy.content.paths:/**,/*.png",
"spring.resources.chain.strategy.fixed.enabled:true", "spring.resources.chain.strategy.fixed.enabled:true",
"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.html5AppCache:true"); "spring.resources.chain.html5AppCache:true");
this.context.register(Config.class, WebMvcAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
assertThat(getResourceResolvers("/webjars/**").size(), equalTo(2)); assertThat(getResourceResolvers("/webjars/**").size(), equalTo(2));
assertThat(getResourceTransformers("/webjars/**").size(), equalTo(2)); assertThat(getResourceTransformers("/webjars/**").size(), equalTo(2));
assertThat(getResourceResolvers("/**").size(), equalTo(2)); assertThat(getResourceResolvers("/**").size(), equalTo(2));
......
...@@ -129,7 +129,7 @@ content into your application; rather pick only the properties that you need. ...@@ -129,7 +129,7 @@ content into your application; rather pick only the properties that you need.
# SPRING RESOURCES HANDLING ({sc-spring-boot-autoconfigure}/web/ResourceProperties.{sc-ext}[ResourceProperties]) # SPRING RESOURCES HANDLING ({sc-spring-boot-autoconfigure}/web/ResourceProperties.{sc-ext}[ResourceProperties])
spring.resources.cache-period= # cache timeouts in headers sent to browser spring.resources.cache-period= # cache timeouts in headers sent to browser
spring.resources.add-mappings=true # if default mappings should be added spring.resources.add-mappings=true # if default mappings should be added
spring.resources.chain.enabled=false # enable the Spring Resource Handling chain spring.resources.chain.enabled=false # enable the Spring Resource Handling chain (enabled automatically if at least a strategy is enabled)
spring.resources.chain.cache=false # enable in-memory caching of resource resolution spring.resources.chain.cache=false # enable in-memory caching of resource resolution
spring.resources.chain.html5AppCache=false # enable HTML5 appcache manifest rewriting spring.resources.chain.html5AppCache=false # enable HTML5 appcache manifest rewriting
spring.resources.chain.strategy.content.enabled=false # enable a content version strategy spring.resources.chain.strategy.content.enabled=false # enable a content version strategy
......
...@@ -1193,7 +1193,6 @@ for all static resources, effectively adding a content hash in URLs, such as ...@@ -1193,7 +1193,6 @@ for all static resources, effectively adding a content hash in URLs, such as
[source,properties,indent=0,subs="verbatim,quotes,attributes"] [source,properties,indent=0,subs="verbatim,quotes,attributes"]
---- ----
spring.resources.chain.enabled=true
spring.resources.chain.strategy.content.enabled=true spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/** spring.resources.chain.strategy.content.paths=/**
---- ----
...@@ -1210,7 +1209,6 @@ A "fixed" strategy will add a static version string in the URL, without changing ...@@ -1210,7 +1209,6 @@ A "fixed" strategy will add a static version string in the URL, without changing
[source,properties,indent=0,subs="verbatim,quotes,attributes"] [source,properties,indent=0,subs="verbatim,quotes,attributes"]
---- ----
spring.resources.chain.enabled=true
spring.resources.chain.strategy.content.enabled=true spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/** spring.resources.chain.strategy.content.paths=/**
spring.resources.chain.strategy.fixed.enabled=true spring.resources.chain.strategy.fixed.enabled=true
...@@ -1225,9 +1223,12 @@ the content one `<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/> ...@@ -1225,9 +1223,12 @@ the content one `<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>
See {sc-spring-boot-autoconfigure}/web/ResourceProperties.{sc-ext}[`ResourceProperties`] See {sc-spring-boot-autoconfigure}/web/ResourceProperties.{sc-ext}[`ResourceProperties`]
for more of the supported options. for more of the supported options.
[TIP]
====
This feature has been thoroughly described in a dedicated This feature has been thoroughly described in a dedicated
https://spring.io/blog/2014/07/24/spring-framework-4-1-handling-static-web-resources[blog post] https://spring.io/blog/2014/07/24/spring-framework-4-1-handling-static-web-resources[blog post]
and in Spring Framework's {spring-reference}/#mvc-config-static-resources[reference documentation]. and in Spring Framework's {spring-reference}/#mvc-config-static-resources[reference documentation].
====
[[boot-features-spring-mvc-template-engines]] [[boot-features-spring-mvc-template-engines]]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment