Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
DEMO
spring-boot
Commits
a990cc18
Commit
a990cc18
authored
Jun 28, 2015
by
Stephane Nicoll
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #3123 from bclozel/gh-1604
* pr/3123: Polish Improve Spring Resource Handling support
parents
e34bdcdd
a6ccb4a6
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
400 additions
and
4 deletions
+400
-4
ThymeleafAutoConfiguration.java
...t/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java
+14
-0
VelocityAutoConfiguration.java
...oot/autoconfigure/velocity/VelocityAutoConfiguration.java
+8
-0
ResourceProperties.java
...gframework/boot/autoconfigure/web/ResourceProperties.java
+165
-1
WebMvcAutoConfiguration.java
...ework/boot/autoconfigure/web/WebMvcAutoConfiguration.java
+34
-2
ThymeleafAutoConfigurationTests.java
...oconfigure/thymeleaf/ThymeleafAutoConfigurationTests.java
+11
-1
VelocityAutoConfigurationTests.java
...utoconfigure/velocity/VelocityAutoConfigurationTests.java
+8
-0
WebMvcAutoConfigurationTests.java
.../boot/autoconfigure/web/WebMvcAutoConfigurationTests.java
+106
-0
appendix-application-properties.adoc
...cs/src/main/asciidoc/appendix-application-properties.adoc
+8
-0
spring-boot-features.adoc
spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc
+46
-0
No files found.
spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfiguration.java
View file @
a990cc18
...
@@ -39,6 +39,7 @@ import org.springframework.context.annotation.Bean;
...
@@ -39,6 +39,7 @@ import org.springframework.context.annotation.Bean;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.core.Ordered
;
import
org.springframework.core.Ordered
;
import
org.springframework.util.Assert
;
import
org.springframework.util.Assert
;
import
org.springframework.web.servlet.resource.ResourceUrlEncodingFilter
;
import
org.thymeleaf.dialect.IDialect
;
import
org.thymeleaf.dialect.IDialect
;
import
org.thymeleaf.extras.conditionalcomments.dialect.ConditionalCommentsDialect
;
import
org.thymeleaf.extras.conditionalcomments.dialect.ConditionalCommentsDialect
;
import
org.thymeleaf.extras.springsecurity4.dialect.SpringSecurityDialect
;
import
org.thymeleaf.extras.springsecurity4.dialect.SpringSecurityDialect
;
...
@@ -56,6 +57,7 @@ import com.github.mxab.thymeleaf.extras.dataattribute.dialect.DataAttributeDiale
...
@@ -56,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
)
...
@@ -213,4 +215,16 @@ public class ThymeleafAutoConfiguration {
...
@@ -213,4 +215,16 @@ public class ThymeleafAutoConfiguration {
}
}
@Configuration
@ConditionalOnWebApplication
protected
static
class
ThymeleafResourceHandlingConfig
{
@Bean
@ConditionalOnMissingBean
public
ResourceUrlEncodingFilter
resourceUrlEncodingFilter
()
{
return
new
ResourceUrlEncodingFilter
();
}
}
}
}
spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/velocity/VelocityAutoConfiguration.java
View file @
a990cc18
...
@@ -42,6 +42,7 @@ import org.springframework.context.annotation.Configuration;
...
@@ -42,6 +42,7 @@ import org.springframework.context.annotation.Configuration;
import
org.springframework.ui.velocity.VelocityEngineFactory
;
import
org.springframework.ui.velocity.VelocityEngineFactory
;
import
org.springframework.ui.velocity.VelocityEngineFactoryBean
;
import
org.springframework.ui.velocity.VelocityEngineFactoryBean
;
import
org.springframework.util.Assert
;
import
org.springframework.util.Assert
;
import
org.springframework.web.servlet.resource.ResourceUrlEncodingFilter
;
import
org.springframework.web.servlet.view.velocity.VelocityConfig
;
import
org.springframework.web.servlet.view.velocity.VelocityConfig
;
import
org.springframework.web.servlet.view.velocity.VelocityConfigurer
;
import
org.springframework.web.servlet.view.velocity.VelocityConfigurer
;
import
org.springframework.web.servlet.view.velocity.VelocityViewResolver
;
import
org.springframework.web.servlet.view.velocity.VelocityViewResolver
;
...
@@ -50,6 +51,7 @@ import org.springframework.web.servlet.view.velocity.VelocityViewResolver;
...
@@ -50,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
...
@@ -134,6 +136,12 @@ public class VelocityAutoConfiguration {
...
@@ -134,6 +136,12 @@ public class VelocityAutoConfiguration {
return
resolver
;
return
resolver
;
}
}
@Bean
@ConditionalOnMissingBean
public
ResourceUrlEncodingFilter
resourceUrlEncodingFilter
()
{
return
new
ResourceUrlEncodingFilter
();
}
}
}
}
}
spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/ResourceProperties.java
View file @
a990cc18
/*
/*
* Copyright 2012-201
4
the original author or authors.
* Copyright 2012-201
5
the original author or authors.
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* you may not use this file except in compliance with the License.
...
@@ -16,12 +16,15 @@
...
@@ -16,12 +16,15 @@
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
;
/**
/**
* Properties used to configure resource handling.
* Properties used to configure resource handling.
*
*
* @author Phillip Webb
* @author Phillip Webb
* @author Brian Clozel
* @since 1.1.0
* @since 1.1.0
*/
*/
@ConfigurationProperties
(
prefix
=
"spring.resources"
,
ignoreUnknownFields
=
false
)
@ConfigurationProperties
(
prefix
=
"spring.resources"
,
ignoreUnknownFields
=
false
)
...
@@ -37,6 +40,17 @@ public class ResourceProperties {
...
@@ -37,6 +40,17 @@ public class ResourceProperties {
*/
*/
private
boolean
addMappings
=
true
;
private
boolean
addMappings
=
true
;
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
;
}
}
...
@@ -53,4 +67,154 @@ public class ResourceProperties {
...
@@ -53,4 +67,154 @@ public class ResourceProperties {
this
.
addMappings
=
addMappings
;
this
.
addMappings
=
addMappings
;
}
}
public
Chain
getChain
()
{
return
chain
;
}
/**
* Configuration for the Spring Resource Handling chain.
*/
public
static
class
Chain
{
/**
* Enable the Spring Resource Handling chain. Disabled by default unless
* at least one strategy has been enabled.
*/
private
Boolean
enabled
;
/**
* Enable caching in the Resource chain.
*/
private
boolean
cache
=
true
;
/**
* Enable HTML5 app cache manifest rewriting.
*/
private
boolean
html5AppCache
=
false
;
private
final
Strategy
strategy
=
new
Strategy
();
public
Boolean
getEnabled
()
{
return
enabled
;
}
public
void
setEnabled
(
boolean
enabled
)
{
this
.
enabled
=
enabled
;
}
public
boolean
isCache
()
{
return
cache
;
}
public
void
setCache
(
boolean
cache
)
{
this
.
cache
=
cache
;
}
public
Strategy
getStrategy
()
{
return
strategy
;
}
public
boolean
isHtml5AppCache
()
{
return
html5AppCache
;
}
public
void
setHtml5AppCache
(
boolean
html5AppCache
)
{
this
.
html5AppCache
=
html5AppCache
;
}
}
/**
* Strategies for extracting and embedding a resource version in its URL path.
*/
public
static
class
Strategy
{
private
final
Fixed
fixed
=
new
Fixed
();
private
final
Content
content
=
new
Content
();
public
Fixed
getFixed
()
{
return
fixed
;
}
public
Content
getContent
()
{
return
content
;
}
}
/**
* Version Strategy based on content hashing.
*/
public
static
class
Content
{
/**
* Enable the content Version Strategy.
*/
private
boolean
enabled
;
/**
* Comma-separated list of patterns to apply to the Version Strategy.
*/
private
String
[]
paths
=
new
String
[]{
"/**"
};
public
boolean
isEnabled
()
{
return
enabled
;
}
public
void
setEnabled
(
boolean
enabled
)
{
this
.
enabled
=
enabled
;
}
public
String
[]
getPaths
()
{
return
paths
;
}
public
void
setPaths
(
String
[]
paths
)
{
this
.
paths
=
paths
;
}
}
/**
* Version Strategy based on a fixed version string.
*/
public
static
class
Fixed
{
/**
* Enable the fixed Version Strategy.
*/
private
boolean
enabled
;
/**
* Comma-separated list of patterns to apply to the Version Strategy.
*/
private
String
[]
paths
;
/**
* Version string to use for the Version Strategy.
*/
private
String
version
;
public
boolean
isEnabled
()
{
return
enabled
;
}
public
void
setEnabled
(
boolean
enabled
)
{
this
.
enabled
=
enabled
;
}
public
String
[]
getPaths
()
{
return
paths
;
}
public
void
setPaths
(
String
[]
paths
)
{
this
.
paths
=
paths
;
}
public
String
getVersion
()
{
return
version
;
}
public
void
setVersion
(
String
version
)
{
this
.
version
=
version
;
}
}
}
}
spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.java
View file @
a990cc18
...
@@ -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
;
...
@@ -68,6 +69,8 @@ import org.springframework.web.servlet.ViewResolver;
...
@@ -68,6 +69,8 @@ import org.springframework.web.servlet.ViewResolver;
import
org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer
;
import
org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer
;
import
org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration
;
import
org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration
;
import
org.springframework.web.servlet.config.annotation.EnableWebMvc
;
import
org.springframework.web.servlet.config.annotation.EnableWebMvc
;
import
org.springframework.web.servlet.config.annotation.ResourceChainRegistration
;
import
org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration
;
import
org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
;
import
org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry
;
import
org.springframework.web.servlet.config.annotation.ViewControllerRegistry
;
import
org.springframework.web.servlet.config.annotation.ViewControllerRegistry
;
import
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport
;
import
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport
;
...
@@ -76,7 +79,9 @@ import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
...
@@ -76,7 +79,9 @@ import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import
org.springframework.web.servlet.i18n.FixedLocaleResolver
;
import
org.springframework.web.servlet.i18n.FixedLocaleResolver
;
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.ResourceHttpRequestHandler
;
import
org.springframework.web.servlet.resource.ResourceHttpRequestHandler
;
import
org.springframework.web.servlet.resource.VersionResourceResolver
;
import
org.springframework.web.servlet.view.BeanNameViewResolver
;
import
org.springframework.web.servlet.view.BeanNameViewResolver
;
import
org.springframework.web.servlet.view.ContentNegotiatingViewResolver
;
import
org.springframework.web.servlet.view.ContentNegotiatingViewResolver
;
import
org.springframework.web.servlet.view.InternalResourceViewResolver
;
import
org.springframework.web.servlet.view.InternalResourceViewResolver
;
...
@@ -255,14 +260,41 @@ public class WebMvcAutoConfiguration {
...
@@ -255,14 +260,41 @@ public class WebMvcAutoConfiguration {
}
}
Integer
cachePeriod
=
this
.
resourceProperties
.
getCachePeriod
();
Integer
cachePeriod
=
this
.
resourceProperties
.
getCachePeriod
();
if
(!
registry
.
hasMappingForPattern
(
"/webjars/**"
))
{
if
(!
registry
.
hasMappingForPattern
(
"/webjars/**"
))
{
registry
.
addResourceHandler
(
"/webjars/**"
)
ResourceHandlerRegistration
registration
=
registry
.
addResourceHandler
(
"/webjars/**"
)
.
addResourceLocations
(
"classpath:/META-INF/resources/webjars/"
)
.
addResourceLocations
(
"classpath:/META-INF/resources/webjars/"
)
.
setCachePeriod
(
cachePeriod
);
.
setCachePeriod
(
cachePeriod
);
registerResourceChain
(
registration
);
}
}
if
(!
registry
.
hasMappingForPattern
(
"/**"
))
{
if
(!
registry
.
hasMappingForPattern
(
"/**"
))
{
registry
.
addResourceHandler
(
"/**"
)
ResourceHandlerRegistration
registration
=
registry
.
addResourceHandler
(
"/**"
)
.
addResourceLocations
(
RESOURCE_LOCATIONS
)
.
addResourceLocations
(
RESOURCE_LOCATIONS
)
.
setCachePeriod
(
cachePeriod
);
.
setCachePeriod
(
cachePeriod
);
registerResourceChain
(
registration
);
}
}
private
void
registerResourceChain
(
ResourceHandlerRegistration
registration
)
{
ResourceProperties
.
Chain
chainProperties
=
this
.
resourceProperties
.
getChain
();
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
();
if
(
hasFixedVersionConfigured
||
hasContentVersionConfigured
)
{
VersionResourceResolver
versionResourceResolver
=
new
VersionResourceResolver
();
if
(
hasFixedVersionConfigured
)
{
versionResourceResolver
.
addFixedVersionStrategy
(
chainProperties
.
getStrategy
().
getFixed
().
getVersion
(),
chainProperties
.
getStrategy
().
getFixed
().
getPaths
());
}
if
(
hasContentVersionConfigured
)
{
versionResourceResolver
.
addContentVersionStrategy
(
chainProperties
.
getStrategy
().
getContent
().
getPaths
());
}
chain
.
addResolver
(
versionResourceResolver
);
}
if
(
chainProperties
.
isHtml5AppCache
())
{
chain
.
addTransformer
(
new
AppCacheManifestTransformer
());
}
}
}
}
}
...
...
spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/thymeleaf/ThymeleafAutoConfigurationTests.java
View file @
a990cc18
/*
/*
* Copyright 2012-201
4
the original author or authors.
* Copyright 2012-201
5
the original author or authors.
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* you may not use this file except in compliance with the License.
...
@@ -31,6 +31,7 @@ import org.springframework.mock.web.MockHttpServletResponse;
...
@@ -31,6 +31,7 @@ import org.springframework.mock.web.MockHttpServletResponse;
import
org.springframework.mock.web.MockServletContext
;
import
org.springframework.mock.web.MockServletContext
;
import
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
;
import
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
;
import
org.springframework.web.servlet.ViewResolver
;
import
org.springframework.web.servlet.ViewResolver
;
import
org.springframework.web.servlet.resource.ResourceUrlEncodingFilter
;
import
org.springframework.web.servlet.support.RequestContext
;
import
org.springframework.web.servlet.support.RequestContext
;
import
org.thymeleaf.TemplateEngine
;
import
org.thymeleaf.TemplateEngine
;
import
org.thymeleaf.context.Context
;
import
org.thymeleaf.context.Context
;
...
@@ -42,6 +43,7 @@ import org.thymeleaf.templateresolver.TemplateResolver;
...
@@ -42,6 +43,7 @@ import org.thymeleaf.templateresolver.TemplateResolver;
import
static
org
.
hamcrest
.
Matchers
.
containsString
;
import
static
org
.
hamcrest
.
Matchers
.
containsString
;
import
static
org
.
junit
.
Assert
.
assertArrayEquals
;
import
static
org
.
junit
.
Assert
.
assertArrayEquals
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
import
static
org
.
junit
.
Assert
.
assertTrue
;
...
@@ -180,4 +182,12 @@ public class ThymeleafAutoConfigurationTests {
...
@@ -180,4 +182,12 @@ public class ThymeleafAutoConfigurationTests {
}
}
}
}
@Test
public
void
registerResourceHandlingFilter
()
throws
Exception
{
this
.
context
.
register
(
ThymeleafAutoConfiguration
.
class
,
PropertyPlaceholderAutoConfiguration
.
class
);
this
.
context
.
refresh
();
assertNotNull
(
this
.
context
.
getBean
(
ResourceUrlEncodingFilter
.
class
));
}
}
}
spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/velocity/VelocityAutoConfigurationTests.java
View file @
a990cc18
...
@@ -37,6 +37,7 @@ import org.springframework.mock.web.MockHttpServletResponse;
...
@@ -37,6 +37,7 @@ import org.springframework.mock.web.MockHttpServletResponse;
import
org.springframework.mock.web.MockServletContext
;
import
org.springframework.mock.web.MockServletContext
;
import
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
;
import
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
;
import
org.springframework.web.servlet.View
;
import
org.springframework.web.servlet.View
;
import
org.springframework.web.servlet.resource.ResourceUrlEncodingFilter
;
import
org.springframework.web.servlet.support.RequestContext
;
import
org.springframework.web.servlet.support.RequestContext
;
import
org.springframework.web.servlet.view.velocity.VelocityConfigurer
;
import
org.springframework.web.servlet.view.velocity.VelocityConfigurer
;
import
org.springframework.web.servlet.view.velocity.VelocityViewResolver
;
import
org.springframework.web.servlet.view.velocity.VelocityViewResolver
;
...
@@ -45,6 +46,7 @@ import static org.hamcrest.Matchers.containsString;
...
@@ -45,6 +46,7 @@ import static org.hamcrest.Matchers.containsString;
import
static
org
.
hamcrest
.
Matchers
.
equalTo
;
import
static
org
.
hamcrest
.
Matchers
.
equalTo
;
import
static
org
.
hamcrest
.
Matchers
.
instanceOf
;
import
static
org
.
hamcrest
.
Matchers
.
instanceOf
;
import
static
org
.
hamcrest
.
Matchers
.
notNullValue
;
import
static
org
.
hamcrest
.
Matchers
.
notNullValue
;
import
static
org
.
junit
.
Assert
.
assertNotNull
;
import
static
org
.
junit
.
Assert
.
assertThat
;
import
static
org
.
junit
.
Assert
.
assertThat
;
/**
/**
...
@@ -183,6 +185,12 @@ public class VelocityAutoConfigurationTests {
...
@@ -183,6 +185,12 @@ public class VelocityAutoConfigurationTests {
assertThat
(
resolver
,
instanceOf
(
EmbeddedVelocityViewResolver
.
class
));
assertThat
(
resolver
,
instanceOf
(
EmbeddedVelocityViewResolver
.
class
));
}
}
@Test
public
void
registerResourceHandlingFilter
()
throws
Exception
{
registerAndRefreshContext
();
assertNotNull
(
this
.
context
.
getBean
(
ResourceUrlEncodingFilter
.
class
));
}
private
void
registerAndRefreshContext
(
String
...
env
)
{
private
void
registerAndRefreshContext
(
String
...
env
)
{
EnvironmentTestUtils
.
addEnvironment
(
this
.
context
,
env
);
EnvironmentTestUtils
.
addEnvironment
(
this
.
context
,
env
);
this
.
context
.
register
(
VelocityAutoConfiguration
.
class
);
this
.
context
.
register
(
VelocityAutoConfiguration
.
class
);
...
...
spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/WebMvcAutoConfigurationTests.java
View file @
a990cc18
...
@@ -60,10 +60,21 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
...
@@ -60,10 +60,21 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
import
org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
;
import
org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
;
import
org.springframework.web.servlet.i18n.FixedLocaleResolver
;
import
org.springframework.web.servlet.i18n.FixedLocaleResolver
;
import
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
;
import
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
;
import
org.springframework.web.servlet.resource.AppCacheManifestTransformer
;
import
org.springframework.web.servlet.resource.CachingResourceResolver
;
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.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.ResourceTransformer
;
import
org.springframework.web.servlet.resource.VersionResourceResolver
;
import
org.springframework.web.servlet.view.AbstractView
;
import
org.springframework.web.servlet.view.AbstractView
;
import
org.springframework.web.servlet.view.ContentNegotiatingViewResolver
;
import
org.springframework.web.servlet.view.ContentNegotiatingViewResolver
;
import
static
org
.
hamcrest
.
Matchers
.
contains
;
import
static
org
.
hamcrest
.
Matchers
.
equalTo
;
import
static
org
.
hamcrest
.
Matchers
.
equalTo
;
import
static
org
.
hamcrest
.
Matchers
.
instanceOf
;
import
static
org
.
hamcrest
.
Matchers
.
instanceOf
;
import
static
org
.
hamcrest
.
Matchers
.
is
;
import
static
org
.
hamcrest
.
Matchers
.
is
;
...
@@ -82,6 +93,7 @@ import static org.junit.Assert.assertThat;
...
@@ -82,6 +93,7 @@ import static org.junit.Assert.assertThat;
* @author Dave Syer
* @author Dave Syer
* @author Andy Wilkinson
* @author Andy Wilkinson
* @author Stephane Nicoll
* @author Stephane Nicoll
* @author Brian Clozel
*/
*/
public
class
WebMvcAutoConfigurationTests
{
public
class
WebMvcAutoConfigurationTests
{
...
@@ -124,6 +136,10 @@ public class WebMvcAutoConfigurationTests {
...
@@ -124,6 +136,10 @@ public class WebMvcAutoConfigurationTests {
assertThat
(
mappingLocations
.
get
(
"/webjars/**"
).
size
(),
equalTo
(
1
));
assertThat
(
mappingLocations
.
get
(
"/webjars/**"
).
size
(),
equalTo
(
1
));
assertThat
(
mappingLocations
.
get
(
"/webjars/**"
).
get
(
0
),
assertThat
(
mappingLocations
.
get
(
"/webjars/**"
).
get
(
0
),
equalTo
((
Resource
)
new
ClassPathResource
(
"/META-INF/resources/webjars/"
)));
equalTo
((
Resource
)
new
ClassPathResource
(
"/META-INF/resources/webjars/"
)));
assertThat
(
getResourceResolvers
(
"/webjars/**"
).
size
(),
equalTo
(
1
));
assertThat
(
getResourceTransformers
(
"/webjars/**"
).
size
(),
equalTo
(
0
));
assertThat
(
getResourceResolvers
(
"/**"
).
size
(),
equalTo
(
1
));
assertThat
(
getResourceTransformers
(
"/**"
).
size
(),
equalTo
(
0
));
}
}
@Test
@Test
...
@@ -151,6 +167,84 @@ public class WebMvcAutoConfigurationTests {
...
@@ -151,6 +167,84 @@ public class WebMvcAutoConfigurationTests {
assertThat
(
mappingLocations
.
size
(),
equalTo
(
0
));
assertThat
(
mappingLocations
.
size
(),
equalTo
(
0
));
}
}
@Test
public
void
resourceHandlerChainEnabled
()
throws
Exception
{
load
(
"spring.resources.chain.enabled:true"
);
assertThat
(
getResourceResolvers
(
"/webjars/**"
).
size
(),
equalTo
(
2
));
assertThat
(
getResourceTransformers
(
"/webjars/**"
).
size
(),
equalTo
(
1
));
assertThat
(
getResourceResolvers
(
"/**"
).
size
(),
equalTo
(
2
));
assertThat
(
getResourceTransformers
(
"/**"
).
size
(),
equalTo
(
1
));
assertThat
(
getResourceResolvers
(
"/**"
),
contains
(
instanceOf
(
CachingResourceResolver
.
class
),
instanceOf
(
PathResourceResolver
.
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
public
void
resourceHandlerChainCustomized
()
throws
Exception
{
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"
);
assertThat
(
getResourceResolvers
(
"/webjars/**"
).
size
(),
equalTo
(
2
));
assertThat
(
getResourceTransformers
(
"/webjars/**"
).
size
(),
equalTo
(
2
));
assertThat
(
getResourceResolvers
(
"/**"
).
size
(),
equalTo
(
2
));
assertThat
(
getResourceTransformers
(
"/**"
).
size
(),
equalTo
(
2
));
assertThat
(
getResourceResolvers
(
"/**"
),
contains
(
instanceOf
(
VersionResourceResolver
.
class
),
instanceOf
(
PathResourceResolver
.
class
)));
assertThat
(
getResourceTransformers
(
"/**"
),
contains
(
instanceOf
(
CssLinkResourceTransformer
.
class
),
instanceOf
(
AppCacheManifestTransformer
.
class
)));
VersionResourceResolver
resolver
=
(
VersionResourceResolver
)
getResourceResolvers
(
"/**"
).
get
(
0
);
assertThat
(
resolver
.
getStrategyMap
().
get
(
"/*.png"
),
instanceOf
(
ContentVersionStrategy
.
class
));
assertThat
(
resolver
.
getStrategyMap
().
get
(
"/**/*.js"
),
instanceOf
(
FixedVersionStrategy
.
class
));
}
@Test
@Test
public
void
noLocaleResolver
()
throws
Exception
{
public
void
noLocaleResolver
()
throws
Exception
{
load
(
AllResources
.
class
);
load
(
AllResources
.
class
);
...
@@ -220,6 +314,18 @@ public class WebMvcAutoConfigurationTests {
...
@@ -220,6 +314,18 @@ public class WebMvcAutoConfigurationTests {
return
getMappingLocations
(
mapping
);
return
getMappingLocations
(
mapping
);
}
}
protected
List
<
ResourceResolver
>
getResourceResolvers
(
String
mapping
)
{
SimpleUrlHandlerMapping
handler
=
(
SimpleUrlHandlerMapping
)
this
.
context
.
getBean
(
"resourceHandlerMapping"
);
ResourceHttpRequestHandler
resourceHandler
=
(
ResourceHttpRequestHandler
)
handler
.
getHandlerMap
().
get
(
mapping
);
return
resourceHandler
.
getResourceResolvers
();
}
protected
List
<
ResourceTransformer
>
getResourceTransformers
(
String
mapping
)
{
SimpleUrlHandlerMapping
handler
=
(
SimpleUrlHandlerMapping
)
this
.
context
.
getBean
(
"resourceHandlerMapping"
);
ResourceHttpRequestHandler
resourceHandler
=
(
ResourceHttpRequestHandler
)
handler
.
getHandlerMap
().
get
(
mapping
);
return
resourceHandler
.
getResourceTransformers
();
}
@SuppressWarnings
(
"unchecked"
)
@SuppressWarnings
(
"unchecked"
)
protected
Map
<
String
,
List
<
Resource
>>
getMappingLocations
(
HandlerMapping
mapping
)
protected
Map
<
String
,
List
<
Resource
>>
getMappingLocations
(
HandlerMapping
mapping
)
throws
IllegalAccessException
{
throws
IllegalAccessException
{
...
...
spring-boot-docs/src/main/asciidoc/appendix-application-properties.adoc
View file @
a990cc18
...
@@ -129,6 +129,14 @@ content into your application; rather pick only the properties that you need.
...
@@ -129,6 +129,14 @@ 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 (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
spring.resources.chain.strategy.content.paths= # comma-separated list of regular expression patterns to apply the version strategy to
spring.resources.chain.strategy.fixed.enabled=false # enable a fixed version strategy
spring.resources.chain.strategy.fixed.paths= # comma-separated list of regular expression patterns to apply the version strategy to
spring.resources.chain.strategy.fixed.version= # version string to use for this version strategy
# MULTIPART ({sc-spring-boot-autoconfigure}/web/MultipartProperties.{sc-ext}[MultipartProperties])
# MULTIPART ({sc-spring-boot-autoconfigure}/web/MultipartProperties.{sc-ext}[MultipartProperties])
multipart.enabled=true
multipart.enabled=true
...
...
spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc
View file @
a990cc18
...
@@ -1183,6 +1183,52 @@ TIP: Do not use the `src/main/webapp` directory if your application will be pack
...
@@ -1183,6 +1183,52 @@ TIP: Do not use the `src/main/webapp` directory if your application will be pack
jar. Although this directory is a common standard, it will *only* work with war packaging
jar. Although this directory is a common standard, it will *only* work with war packaging
and it will be silently ignored by most build tools if you generate a jar.
and it will be silently ignored by most build tools if you generate a jar.
Spring Boot also supports advanced resource handling features provided by Spring MVC,
allowing use cases such as cache busting static resources or using version agnostic URLs
for Webjars.
For example, the following configuration will configure a cache busting solution
for all static resources, effectively adding a content hash in URLs, such as
`<link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>`:
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
----
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
----
NOTE: Links to resources are rewritten at runtime in template, thanks to a
`ResourceUrlEncodingFilter`, auto-configured for Thymeleaf and Velocity. You should
manually declare this filter when using JSPs. Other template engines aren't automatically
supported right now, but can be with custom template macros/helpers and the use of the
{spring-javadoc}/web/servlet/resource/ResourceUrlProvider.{dc-ext}[`ResourceUrlProvider`].
When loading resources dynamically with, for example, a JavaScript module loader, renaming
files is not an option. That's why other strategies are also supported and can be combined.
A "fixed" strategy will add a static version string in the URL, without changing the file name:
[source,properties,indent=0,subs="verbatim,quotes,attributes"]
----
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
spring.resources.chain.strategy.fixed.enabled=true
spring.resources.chain.strategy.fixed.paths=/js/lib/
spring.resources.chain.strategy.fixed.version=v12
----
With this configuration, JavaScript modules located under `"/js/lib/"` will use a fixed
versioning strategy `"/v12/js/lib/mymodule.js"` while other resources will still use
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]]
[[boot-features-spring-mvc-template-engines]]
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment