Set ETag header with VersionResourceResolver
Prior to this change, VersionResourceResolver and VersionStrategy would resolve static resources using version strings. They assist ResourceHttpRequestHandler with serving static resources. The RequestHandler itself can be configured with HTTP caching strategies to set Cache-Control headers. In order to have a complete strategy with Cache-Control and ETag response headers, developers can't reuse that version string information and have to rely on other mechanisms (like ShallowEtagHeaderFilter). This commit makes VersionResourceResolver use that version string to set it as a request attribute, which will be used by the ResourceHttpRequestHandler to write an ETag response header. Issue: SPR-13382
This commit is contained in:
@@ -89,13 +89,12 @@ import org.springframework.web.servlet.support.WebContentGenerator;
|
||||
* @author Jeremy Grelle
|
||||
* @author Juergen Hoeller
|
||||
* @author Arjen Poutsma
|
||||
* @author Brian Clozel
|
||||
* @since 3.0.4
|
||||
*/
|
||||
public class ResourceHttpRequestHandler extends WebContentGenerator
|
||||
implements HttpRequestHandler, InitializingBean, CorsConfigurationSource {
|
||||
|
||||
private static final String CONTENT_ENCODING = "Content-Encoding";
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ResourceHttpRequestHandler.class);
|
||||
|
||||
private static final boolean jafPresent = ClassUtils.isPresent(
|
||||
@@ -267,6 +266,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
|
||||
}
|
||||
|
||||
if (request.getHeader(HttpHeaders.RANGE) == null) {
|
||||
setETagHeader(request, response);
|
||||
setHeaders(response, resource, mediaType);
|
||||
writeContent(response, resource);
|
||||
}
|
||||
@@ -406,6 +406,21 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
|
||||
return mediaType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ETag header if the version string of the served resource is present.
|
||||
* Version strings can be resolved by {@link VersionStrategy} implementations and then
|
||||
* set as a request attribute by {@link VersionResourceResolver}.
|
||||
* @param request current servlet request
|
||||
* @param response current servlet response
|
||||
* @see VersionResourceResolver
|
||||
*/
|
||||
protected void setETagHeader(HttpServletRequest request, HttpServletResponse response) {
|
||||
String versionString = (String) request.getAttribute(VersionResourceResolver.RESOURCE_VERSION_ATTRIBUTE);
|
||||
if(versionString != null) {
|
||||
response.setHeader(HttpHeaders.ETAG, "\"" + versionString + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set headers on the given servlet response.
|
||||
* Called for GET requests as well as HEAD requests.
|
||||
@@ -426,7 +441,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
|
||||
}
|
||||
|
||||
if (resource instanceof EncodedResource) {
|
||||
response.setHeader(CONTENT_ENCODING, ((EncodedResource) resource).getContentEncoding());
|
||||
response.setHeader(HttpHeaders.CONTENT_ENCODING, ((EncodedResource) resource).getContentEncoding());
|
||||
}
|
||||
|
||||
response.setHeader(HttpHeaders.ACCEPT_RANGES, "bytes");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -54,6 +54,8 @@ import org.springframework.util.StringUtils;
|
||||
*/
|
||||
public class VersionResourceResolver extends AbstractResourceResolver {
|
||||
|
||||
public static final String RESOURCE_VERSION_ATTRIBUTE = VersionResourceResolver.class.getName() + ".resourceVersion";
|
||||
|
||||
private AntPathMatcher pathMatcher = new AntPathMatcher();
|
||||
|
||||
/** Map from path pattern -> VersionStrategy */
|
||||
@@ -165,6 +167,9 @@ public class VersionResourceResolver extends AbstractResourceResolver {
|
||||
if (logger.isTraceEnabled()) {
|
||||
logger.trace("resource matches extracted version");
|
||||
}
|
||||
if(request != null) {
|
||||
request.setAttribute(VersionResourceResolver.RESOURCE_VERSION_ATTRIBUTE, candidateVersion);
|
||||
}
|
||||
return baseResource;
|
||||
}
|
||||
else {
|
||||
|
||||
Reference in New Issue
Block a user