public class ResourceHttpRequestHandler extends WebContentGenerator implements HttpRequestHandler, EmbeddedValueResolverAware, InitializingBean, CorsConfigurationSource
HttpRequestHandler
that serves static resources in an optimized way
according to the guidelines of Page Speed, YSlow, etc.
The properties "locations" and "locationValues" accept locations from which static resources can be served by this handler. This can be relative to the root of the web application, or from the classpath, e.g. "classpath:/META-INF/public-web-resources/", allowing convenient packaging and serving of resources such as .js, .css, and others in jar files.
This request handler may also be configured with a
resourcesResolver
and
resourceTransformer
chains to support
arbitrary resolution and transformation of resources being served. By default
a PathResourceResolver
simply finds resources based on the configured
"locations". An application can configure additional resolvers and transformers
such as the VersionResourceResolver
which can resolve and prepare URLs
for resources with a version in the URL.
This handler also properly evaluates the Last-Modified
header
(if present) so that a 304
status code will be returned as appropriate,
avoiding unnecessary overhead for resources that are already cached by the client.
HEADER_CACHE_CONTROL, METHOD_GET, METHOD_HEAD, METHOD_POST
Constructor and Description |
---|
ResourceHttpRequestHandler() |
Modifier and Type | Method and Description |
---|---|
void |
afterPropertiesSet()
Invoked by the containing
BeanFactory after it has set all bean properties
and satisfied BeanFactoryAware , ApplicationContextAware etc. |
ContentNegotiationManager |
getContentNegotiationManager()
Deprecated.
as of 5.2.4
|
CorsConfiguration |
getCorsConfiguration(HttpServletRequest request)
Return the specified CORS configuration.
|
List<Resource> |
getLocations()
Return the configured
List of Resource locations including
both String-based locations provided via
setLocationValues and pre-resolved
Resource locations provided via setLocations . |
protected MediaType |
getMediaType(HttpServletRequest request,
Resource resource)
Determine the media type for the given request and the resource matched
to it.
|
Map<String,MediaType> |
getMediaTypes()
Return the
configured media types. |
protected Resource |
getResource(HttpServletRequest request) |
ResourceHttpMessageConverter |
getResourceHttpMessageConverter()
Return the configured resource converter.
|
ResourceRegionHttpMessageConverter |
getResourceRegionHttpMessageConverter()
Return the configured resource region converter.
|
List<ResourceResolver> |
getResourceResolvers()
Return the list of configured resource resolvers.
|
List<ResourceTransformer> |
getResourceTransformers()
Return the list of configured resource transformers.
|
UrlPathHelper |
getUrlPathHelper()
The configured
UrlPathHelper . |
void |
handleRequest(HttpServletRequest request,
HttpServletResponse response)
Processes a resource request.
|
protected void |
initAllowedLocations()
Look for a
PathResourceResolver among the configured resource
resolvers and set its allowedLocations property (if empty) to
match the locations configured on this class. |
protected PathExtensionContentNegotiationStrategy |
initContentNegotiationStrategy()
Deprecated.
as of 5.2.4 this method returns
null , and if a
sub-class returns an actual instance,the instance is used only as a
source of media type mappings, if it contains any. Please, use
setMediaTypes(Map) instead, or if you need to change behavior,
you can override getMediaType(HttpServletRequest, Resource) . |
protected boolean |
isInvalidPath(String path)
Identifies invalid resource paths.
|
boolean |
isOptimizeLocations()
Return whether to optimize the specified locations through an existence
check on startup, filtering non-existing directories upfront so that
they do not have to be checked on every resource access.
|
boolean |
isUseLastModified()
Return whether the
Resource.lastModified() information is used
to drive HTTP responses when serving static resources. |
protected String |
processPath(String path)
Process the given resource path.
|
void |
setContentNegotiationManager(ContentNegotiationManager contentNegotiationManager)
Deprecated.
as of 5.2.4 in favor of using
setMediaTypes(Map)
with mappings possibly obtained from
ContentNegotiationManager.getMediaTypeMappings() . |
void |
setCorsConfiguration(CorsConfiguration corsConfiguration)
Specify the CORS configuration for resources served by this handler.
|
void |
setEmbeddedValueResolver(StringValueResolver resolver)
Set the StringValueResolver to use for resolving embedded definition values.
|
protected void |
setHeaders(HttpServletResponse response,
Resource resource,
MediaType mediaType)
Set headers on the given servlet response.
|
void |
setLocations(List<Resource> locations)
Configure locations to serve resources from as pre-resourced Resource's.
|
void |
setLocationValues(List<String> locations)
Configure String-based locations to serve resources from.
|
void |
setMediaTypes(Map<String,MediaType> mediaTypes)
Add mappings between file extensions, extracted from the filename of a
static
Resource , and corresponding media type to set on the
response. |
void |
setOptimizeLocations(boolean optimizeLocations)
Set whether to optimize the specified locations through an existence
check on startup, filtering non-existing directories upfront so that
they do not have to be checked on every resource access.
|
void |
setResourceHttpMessageConverter(ResourceHttpMessageConverter messageConverter)
Configure the
ResourceHttpMessageConverter to use. |
void |
setResourceRegionHttpMessageConverter(ResourceRegionHttpMessageConverter messageConverter)
Configure the
ResourceRegionHttpMessageConverter to use. |
void |
setResourceResolvers(List<ResourceResolver> resourceResolvers)
Configure the list of
ResourceResolvers to use. |
void |
setResourceTransformers(List<ResourceTransformer> resourceTransformers)
Configure the list of
ResourceTransformers to use. |
void |
setUrlPathHelper(UrlPathHelper urlPathHelper)
Provide a reference to the
UrlPathHelper used to map requests to
static resources. |
void |
setUseLastModified(boolean useLastModified)
Set whether we should look at the
Resource.lastModified() when
serving resources and use this information to drive "Last-Modified"
HTTP response headers. |
String |
toString() |
applyCacheControl, applyCacheSeconds, applyCacheSeconds, cacheForSeconds, cacheForSeconds, checkAndPrepare, checkAndPrepare, checkRequest, getAllowHeader, getCacheControl, getCacheSeconds, getSupportedMethods, getVaryByRequestHeaders, isAlwaysMustRevalidate, isRequireSession, isUseCacheControlHeader, isUseCacheControlNoStore, isUseExpiresHeader, prepareResponse, preventCaching, setAlwaysMustRevalidate, setCacheControl, setCacheSeconds, setRequireSession, setSupportedMethods, setUseCacheControlHeader, setUseCacheControlNoStore, setUseExpiresHeader, setVaryByRequestHeaders
getServletContext, getTempDir, getWebApplicationContext, initApplicationContext, initServletContext, isContextRequired, setServletContext
getApplicationContext, getMessageSourceAccessor, initApplicationContext, obtainApplicationContext, requiredContextClass, setApplicationContext
public void setLocationValues(List<String> locations)
For example, {"/"
, "classpath:/META-INF/public-web-resources/"
}
allows resources to be served both from the web application root and
from any JAR on the classpath that contains a
/META-INF/public-web-resources/
directory, with resources in the
web application root taking precedence.
For URL-based resources
(e.g. files, HTTP URLs, etc) this method supports a special prefix to
indicate the charset associated with the URL so that relative paths
appended to it can be encoded correctly, for example
"[charset=Windows-31J]https://example.org/path"
.
setLocations(List)
public void setLocations(List<Resource> locations)
setLocationValues(List)
public List<Resource> getLocations()
List
of Resource
locations including
both String-based locations provided via
setLocationValues
and pre-resolved
Resource
locations provided via setLocations
.
Note that the returned list is fully initialized only after
initialization via afterPropertiesSet()
.
Note: As of 5.3.11 the list of locations may be filtered to
exclude those that don't actually exist and therefore the list returned from this
method may be a subset of all given locations. See setOptimizeLocations(boolean)
.
public void setResourceResolvers(@Nullable List<ResourceResolver> resourceResolvers)
ResourceResolvers
to use.
By default PathResourceResolver
is configured. If using this property,
it is recommended to add PathResourceResolver
as the last resolver.
public List<ResourceResolver> getResourceResolvers()
public void setResourceTransformers(@Nullable List<ResourceTransformer> resourceTransformers)
ResourceTransformers
to use.
By default no transformers are configured for use.
public List<ResourceTransformer> getResourceTransformers()
public void setResourceHttpMessageConverter(@Nullable ResourceHttpMessageConverter messageConverter)
ResourceHttpMessageConverter
to use.
By default a ResourceHttpMessageConverter
will be configured.
@Nullable public ResourceHttpMessageConverter getResourceHttpMessageConverter()
public void setResourceRegionHttpMessageConverter(@Nullable ResourceRegionHttpMessageConverter messageConverter)
ResourceRegionHttpMessageConverter
to use.
By default a ResourceRegionHttpMessageConverter
will be configured.
@Nullable public ResourceRegionHttpMessageConverter getResourceRegionHttpMessageConverter()
@Deprecated public void setContentNegotiationManager(@Nullable ContentNegotiationManager contentNegotiationManager)
setMediaTypes(Map)
with mappings possibly obtained from
ContentNegotiationManager.getMediaTypeMappings()
.ContentNegotiationManager
to help determine the
media types for resources being served. If the manager contains a path
extension strategy it will be checked for registered file extension.@Nullable @Deprecated public ContentNegotiationManager getContentNegotiationManager()
public void setMediaTypes(Map<String,MediaType> mediaTypes)
Resource
, and corresponding media type to set on the
response.
Use of this method is typically not necessary since mappings are
otherwise determined via
ServletContext.getMimeType(String)
or via
MediaTypeFactory.getMediaType(Resource)
.
mediaTypes
- media type mappingspublic Map<String,MediaType> getMediaTypes()
configured
media types.public void setCorsConfiguration(CorsConfiguration corsConfiguration)
By default this is not set in which allows cross-origin requests.
@Nullable public CorsConfiguration getCorsConfiguration(HttpServletRequest request)
getCorsConfiguration
in interface CorsConfigurationSource
CorsConfiguration
, or null
if nonepublic void setUrlPathHelper(@Nullable UrlPathHelper urlPathHelper)
UrlPathHelper
used to map requests to
static resources. This helps to derive information about the lookup path
such as whether it is decoded or not.@Nullable public UrlPathHelper getUrlPathHelper()
UrlPathHelper
.public void setUseLastModified(boolean useLastModified)
Resource.lastModified()
when
serving resources and use this information to drive "Last-Modified"
HTTP response headers.
This option is enabled by default and should be turned off if the metadata of the static files should be ignored.
public boolean isUseLastModified()
Resource.lastModified()
information is used
to drive HTTP responses when serving static resources.public void setOptimizeLocations(boolean optimizeLocations)
The default is false
, for defensiveness against zip files
without directory entries which are unable to expose the existence of
a directory upfront. Switch this flag to true
for optimized
access in case of a consistent jar layout with directory entries.
public boolean isOptimizeLocations()
public void setEmbeddedValueResolver(StringValueResolver resolver)
EmbeddedValueResolverAware
setEmbeddedValueResolver
in interface EmbeddedValueResolverAware
public void afterPropertiesSet() throws Exception
InitializingBean
BeanFactory
after it has set all bean properties
and satisfied BeanFactoryAware
, ApplicationContextAware
etc.
This method allows the bean instance to perform validation of its overall configuration and final initialization when all bean properties have been set.
afterPropertiesSet
in interface InitializingBean
Exception
- in the event of misconfiguration (such as failure to set an
essential property) or if initialization fails for any other reasonprotected void initAllowedLocations()
PathResourceResolver
among the configured resource
resolvers and set its allowedLocations
property (if empty) to
match the locations
configured on this class.@Nullable @Deprecated protected PathExtensionContentNegotiationStrategy initContentNegotiationStrategy()
null
, and if a
sub-class returns an actual instance,the instance is used only as a
source of media type mappings, if it contains any. Please, use
setMediaTypes(Map)
instead, or if you need to change behavior,
you can override getMediaType(HttpServletRequest, Resource)
.public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
Checks for the existence of the requested resource in the configured list of locations.
If the resource does not exist, a 404
response will be returned to the client.
If the resource exists, the request will be checked for the presence of the
Last-Modified
header, and its value will be compared against the last-modified
timestamp of the given resource, returning a 304
status code if the
Last-Modified
value is greater. If the resource is newer than the
Last-Modified
value, or the header is not present, the content resource
of the resource will be written to the response with caching headers
set to expire one year in the future.
handleRequest
in interface HttpRequestHandler
request
- current HTTP requestresponse
- current HTTP responseServletException
- in case of general errorsIOException
- in case of I/O errors@Nullable protected Resource getResource(HttpServletRequest request) throws IOException
IOException
protected String processPath(String path)
The default implementation replaces:
" / // foo/bar"
becomes "/foo/bar"
.
protected boolean isInvalidPath(String path)
StringUtils.cleanPath(java.lang.String)
.
valid URL
or would represent one after the leading slash is removed.
Note: this method assumes that leading, duplicate '/' or control characters (e.g. white space) have been trimmed so that the path starts predictably with a single '/' or does not have one.
path
- the path to validatetrue
if the path is invalid, false
otherwise@Nullable protected MediaType getMediaType(HttpServletRequest request, Resource resource)
request
- the current requestresource
- the resource to checknull
if none foundprotected void setHeaders(HttpServletResponse response, Resource resource, @Nullable MediaType mediaType) throws IOException
response
- current servlet responseresource
- the identified resource (never null
)mediaType
- the resource's media type (never null
)IOException
- in case of errors while setting the headers