public class ShallowEtagHeaderFilter extends OncePerRequestFilter
javax.servlet.Filter
that generates an ETag
value based on the
content on the response. This ETag is compared to the If-None-Match
header of the request. If these headers are equal, the response content is
not sent, but rather a 304 "Not Modified"
status instead.
Since the ETag is based on the response content, the response
(e.g. a View
) is still rendered.
As such, this filter only saves bandwidth, not server performance.
NOTE: As of Spring Framework 5.0, this filter uses request/response decorators built on the Servlet 3.1 API.
Modifier and Type | Class and Description |
---|---|
private static class |
ShallowEtagHeaderFilter.HttpStreamingAwareContentCachingResponseWrapper |
Modifier and Type | Field and Description |
---|---|
private static java.lang.String |
DIRECTIVE_NO_STORE |
private static java.lang.String |
HEADER_CACHE_CONTROL |
private static java.lang.String |
HEADER_ETAG |
private static java.lang.String |
HEADER_IF_NONE_MATCH |
private static java.lang.String |
STREAMING_ATTRIBUTE |
private boolean |
writeWeakETag |
ALREADY_FILTERED_SUFFIX
logger
Constructor and Description |
---|
ShallowEtagHeaderFilter() |
Modifier and Type | Method and Description |
---|---|
private boolean |
compareETagHeaderValue(java.lang.String requestETag,
java.lang.String responseETag) |
static void |
disableContentCaching(ServletRequest request)
This method can be used to disable the content caching response wrapper
of the ShallowEtagHeaderFilter.
|
protected void |
doFilterInternal(HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain)
Same contract as for
doFilter , but guaranteed to be
just invoked once per request within a single request thread. |
protected java.lang.String |
generateETagHeaderValue(java.io.InputStream inputStream,
boolean isWeak)
Generate the ETag header value from the given response body byte array.
|
private static boolean |
isContentCachingDisabled(HttpServletRequest request) |
protected boolean |
isEligibleForEtag(HttpServletRequest request,
HttpServletResponse response,
int responseStatusCode,
java.io.InputStream inputStream)
Indicates whether the given request and response are eligible for ETag generation.
|
boolean |
isWriteWeakETag()
Return whether the ETag value written to the response should be weak, as per RFC 7232.
|
void |
setWriteWeakETag(boolean writeWeakETag)
Set whether the ETag value written to the response should be weak, as per RFC 7232.
|
protected boolean |
shouldNotFilterAsyncDispatch()
The default value is
false so that the filter may delay the generation
of an ETag until the last asynchronously dispatched thread. |
private void |
updateResponse(HttpServletRequest request,
HttpServletResponse response) |
doFilter, getAlreadyFilteredAttributeName, isAsyncDispatch, isAsyncStarted, shouldNotFilter, shouldNotFilterErrorDispatch
addRequiredProperty, afterPropertiesSet, createEnvironment, destroy, getEnvironment, getFilterConfig, getFilterName, getServletContext, init, initBeanWrapper, initFilterBean, setBeanName, setEnvironment, setServletContext
private static final java.lang.String HEADER_ETAG
private static final java.lang.String HEADER_IF_NONE_MATCH
private static final java.lang.String HEADER_CACHE_CONTROL
private static final java.lang.String DIRECTIVE_NO_STORE
private static final java.lang.String STREAMING_ATTRIBUTE
private boolean writeWeakETag
public void setWriteWeakETag(boolean writeWeakETag)
Should be configured using an <init-param>
for parameter name
"writeWeakETag" in the filter definition in web.xml
.
public boolean isWriteWeakETag()
protected boolean shouldNotFilterAsyncDispatch()
false
so that the filter may delay the generation
of an ETag until the last asynchronously dispatched thread.shouldNotFilterAsyncDispatch
in class OncePerRequestFilter
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, java.io.IOException
OncePerRequestFilter
doFilter
, but guaranteed to be
just invoked once per request within a single request thread.
See OncePerRequestFilter.shouldNotFilterAsyncDispatch()
for details.
Provides HttpServletRequest and HttpServletResponse arguments instead of the default ServletRequest and ServletResponse ones.
doFilterInternal
in class OncePerRequestFilter
ServletException
java.io.IOException
private void updateResponse(HttpServletRequest request, HttpServletResponse response) throws java.io.IOException
java.io.IOException
protected boolean isEligibleForEtag(HttpServletRequest request, HttpServletResponse response, int responseStatusCode, java.io.InputStream inputStream)
The default implementation returns true
if all conditions match:
2xx
seriesrequest
- the HTTP requestresponse
- the HTTP responseresponseStatusCode
- the HTTP response status codeinputStream
- the response bodytrue
if eligible for ETag generation, false
otherwiseprotected java.lang.String generateETagHeaderValue(java.io.InputStream inputStream, boolean isWeak) throws java.io.IOException
The default implementation generates an MD5 hash.
inputStream
- the response body as an InputStreamisWeak
- whether the generated ETag should be weakjava.io.IOException
DigestUtils
private boolean compareETagHeaderValue(java.lang.String requestETag, java.lang.String responseETag)
public static void disableContentCaching(ServletRequest request)
private static boolean isContentCachingDisabled(HttpServletRequest request)