org.springframework.web.filter
Class ShallowEtagHeaderFilter

java.lang.Object
  extended by org.springframework.web.filter.GenericFilterBean
      extended by org.springframework.web.filter.OncePerRequestFilter
          extended by org.springframework.web.filter.ShallowEtagHeaderFilter
All Implemented Interfaces:
Aware, BeanNameAware, DisposableBean, InitializingBean, EnvironmentAware, ServletContextAware

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 (or View) is still rendered. As such, this filter only saves bandwidth, not server performance.

Since:
3.0
Author:
Arjen Poutsma

Nested Class Summary
private static class ShallowEtagHeaderFilter.ShallowEtagResponseWrapper
          HttpServletRequest wrapper that buffers all content written to the output stream and writer, and allows this content to be retrieved via a byte array.
 
Field Summary
private static java.lang.String HEADER_ETAG
           
private static java.lang.String HEADER_IF_NONE_MATCH
           
 
Fields inherited from class org.springframework.web.filter.OncePerRequestFilter
ALREADY_FILTERED_SUFFIX
 
Fields inherited from class org.springframework.web.filter.GenericFilterBean
logger
 
Constructor Summary
ShallowEtagHeaderFilter()
           
 
Method Summary
private  void copyBodyToResponse(byte[] body, HttpServletResponse response)
           
protected  void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
          Same contract as for doFilter, but guaranteed to be just invoked once per request.
protected  java.lang.String generateETagHeaderValue(byte[] bytes)
          Generate the ETag header value from the given response body byte array.
protected  boolean isEligibleForEtag(HttpServletRequest request, HttpServletResponse response, int responseStatusCode, byte[] responseBody)
          Indicates whether the given request and response are eligible for ETag generation.
 
Methods inherited from class org.springframework.web.filter.OncePerRequestFilter
doFilter, getAlreadyFilteredAttributeName, shouldNotFilter
 
Methods inherited from class org.springframework.web.filter.GenericFilterBean
addRequiredProperty, afterPropertiesSet, destroy, getFilterConfig, getFilterName, getServletContext, init, initBeanWrapper, initFilterBean, setBeanName, setEnvironment, setServletContext
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

HEADER_ETAG

private static java.lang.String HEADER_ETAG

HEADER_IF_NONE_MATCH

private static java.lang.String HEADER_IF_NONE_MATCH
Constructor Detail

ShallowEtagHeaderFilter

public ShallowEtagHeaderFilter()
Method Detail

doFilterInternal

protected void doFilterInternal(HttpServletRequest request,
                                HttpServletResponse response,
                                FilterChain filterChain)
                         throws ServletException,
                                java.io.IOException
Description copied from class: OncePerRequestFilter
Same contract as for doFilter, but guaranteed to be just invoked once per request. Provides HttpServletRequest and HttpServletResponse arguments instead of the default ServletRequest and ServletResponse ones.

Specified by:
doFilterInternal in class OncePerRequestFilter
Throws:
ServletException
java.io.IOException

copyBodyToResponse

private void copyBodyToResponse(byte[] body,
                                HttpServletResponse response)
                         throws java.io.IOException
Throws:
java.io.IOException

isEligibleForEtag

protected boolean isEligibleForEtag(HttpServletRequest request,
                                    HttpServletResponse response,
                                    int responseStatusCode,
                                    byte[] responseBody)
Indicates whether the given request and response are eligible for ETag generation.

The default implementation returns true for response status codes in the 2xx series.

Parameters:
request - the HTTP request
response - the HTTP response
responseStatusCode - the HTTP response status code
responseBody - the response body
Returns:
true if eligible for ETag generation; false otherwise

generateETagHeaderValue

protected java.lang.String generateETagHeaderValue(byte[] bytes)
Generate the ETag header value from the given response body byte array.

The default implementation generates an MD5 hash.

Parameters:
bytes - the response body as byte array
Returns:
the ETag header value
See Also:
DigestUtils