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

See gh-1604
This commit is contained in:
Stephane Nicoll 2015-06-28 06:20:33 -07:00
parent dd561d15cf
commit a6ccb4a6e0
7 changed files with 71 additions and 25 deletions

View File

@ -57,6 +57,7 @@ import com.github.mxab.thymeleaf.extras.dataattribute.dialect.DataAttributeDiale
* @author Dave Syer
* @author Andy Wilkinson
* @author Stephane Nicoll
* @author Brian Clozel
*/
@Configuration
@EnableConfigurationProperties(ThymeleafProperties.class)

View File

@ -51,6 +51,7 @@ import org.springframework.web.servlet.view.velocity.VelocityViewResolver;
* {@link EnableAutoConfiguration Auto-configuration} for Velocity.
*
* @author Andy Wilkinson
* @author Brian Clozel
* @since 1.1.0
*/
@Configuration

View File

@ -16,6 +16,8 @@
package org.springframework.boot.autoconfigure.web;
import javax.annotation.PostConstruct;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
@ -40,6 +42,15 @@ public class ResourceProperties {
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() {
return this.cachePeriod;
}
@ -66,9 +77,10 @@ public class ResourceProperties {
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.
@ -80,9 +92,9 @@ public class ResourceProperties {
*/
private boolean html5AppCache = false;
private Strategy strategy = new Strategy();
private final Strategy strategy = new Strategy();
public boolean isEnabled() {
public Boolean getEnabled() {
return enabled;
}
@ -116,9 +128,9 @@ public class ResourceProperties {
*/
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() {
return fixed;
@ -137,7 +149,7 @@ public class ResourceProperties {
/**
* Enable the content Version Strategy.
*/
private boolean enabled = false;
private boolean enabled;
/**
* Comma-separated list of patterns to apply to the Version Strategy.
@ -169,7 +181,7 @@ public class ResourceProperties {
/**
* Enable the fixed Version Strategy.
*/
private boolean enabled = false;
private boolean enabled;
/**
* Comma-separated list of patterns to apply to the Version Strategy.

View File

@ -55,6 +55,7 @@ import org.springframework.format.Formatter;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.datetime.DateFormatter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.DefaultMessageCodesResolver;
import org.springframework.validation.MessageCodesResolver;
@ -274,7 +275,7 @@ public class WebMvcAutoConfiguration {
private void registerResourceChain(ResourceHandlerRegistration registration) {
ResourceProperties.Chain chainProperties = this.resourceProperties.getChain();
if (chainProperties.isEnabled()) {
if (ObjectUtils.nullSafeEquals(chainProperties.getEnabled(), Boolean.TRUE)) {
ResourceChainRegistration chain = registration.resourceChain(chainProperties.isCache());
boolean hasFixedVersionConfigured = chainProperties.getStrategy().getFixed().isEnabled();
boolean hasContentVersionConfigured = chainProperties.getStrategy().getContent().isEnabled();

View File

@ -169,12 +169,8 @@ public class WebMvcAutoConfigurationTests {
@Test
public void resourceHandlerChainEnabled() throws Exception {
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
EnvironmentTestUtils.addEnvironment(this.context, "spring.resources.chain.enabled:true");
this.context.register(Config.class, WebMvcAutoConfiguration.class,
HttpMessageConvertersAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
load("spring.resources.chain.enabled:true");
assertThat(getResourceResolvers("/webjars/**").size(), equalTo(2));
assertThat(getResourceTransformers("/webjars/**").size(), equalTo(1));
assertThat(getResourceResolvers("/**").size(), equalTo(2));
@ -185,21 +181,55 @@ public class WebMvcAutoConfigurationTests {
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
public void resourceHandlerChainCustomized() throws Exception {
this.context = new AnnotationConfigEmbeddedWebApplicationContext();
EnvironmentTestUtils.addEnvironment(this.context,
"spring.resources.chain.enabled:true", "spring.resources.chain.cache:false",
load("spring.resources.chain.enabled:true", "spring.resources.chain.cache:false",
"spring.resources.chain.strategy.content.enabled:true",
"spring.resources.chain.strategy.content.paths:/**,/*.png",
"spring.resources.chain.strategy.fixed.enabled:true",
"spring.resources.chain.strategy.fixed.version:test",
"spring.resources.chain.strategy.fixed.paths:/**/*.js",
"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(getResourceTransformers("/webjars/**").size(), equalTo(2));
assertThat(getResourceResolvers("/**").size(), equalTo(2));

View File

@ -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.cache-period= # cache timeouts in headers sent to browser
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.html5AppCache=false # enable HTML5 appcache manifest rewriting
spring.resources.chain.strategy.content.enabled=false # enable a content version strategy

View File

@ -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"]
----
spring.resources.chain.enabled=true
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
----
@ -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"]
----
spring.resources.chain.enabled=true
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
spring.resources.chain.strategy.fixed.enabled=true
@ -1225,9 +1223,12 @@ the content one `<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>
See {sc-spring-boot-autoconfigure}/web/ResourceProperties.{sc-ext}[`ResourceProperties`]
for more of the supported options.
[TIP]
====
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]
and in Spring Framework's {spring-reference}/#mvc-config-static-resources[reference documentation].
====
[[boot-features-spring-mvc-template-engines]]