org.springframework.web.filter

## Class ShallowEtagHeaderFilter

- java.lang.Object
- - org.springframework.web.filter.GenericFilterBean
  - - org.springframework.web.filter.OncePerRequestFilter
    - - org.springframework.web.filter.ShallowEtagHeaderFilter

- All Implemented Interfaces:
    Filter, Aware, BeanNameAware, DisposableBean, InitializingBean, EnvironmentAware, ServletContextAware

      public class ShallowEtagHeaderFilter
      extends OncePerRequestFilter

  `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.

  Since:
    3.0
  Author:
    Arjen Poutsma, Rossen Stoyanchev

- - ### Field Summary

    - ### Fields inherited from class org.springframework.web.filter.OncePerRequestFilter

      `ALREADY_FILTERED_SUFFIX`

    - ### Fields inherited from class org.springframework.web.filter.GenericFilterBean

      `logger`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `ShallowEtagHeaderFilter()`

  - ### Method Summary

    All Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `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 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.
    `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.

    - ### Methods inherited from class org.springframework.web.filter.OncePerRequestFilter

      `doFilter, getAlreadyFilteredAttributeName, isAsyncDispatch, isAsyncStarted, shouldNotFilter, shouldNotFilterErrorDispatch`

    - ### 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`

- - ### Constructor Detail

    - #### ShallowEtagHeaderFilter

          public ShallowEtagHeaderFilter()

  - ### Method Detail

    - #### shouldNotFilterAsyncDispatch

          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.
      Overrides:
        `shouldNotFilterAsyncDispatch` in class `OncePerRequestFilter`

    - #### doFilterInternal

          protected void doFilterInternal(HttpServletRequest request,
                                          HttpServletResponse response,
                                          FilterChain filterChain)
                                   throws ServletException,
                                          IOException

      Description copied from class: `OncePerRequestFilter`
      Same contract as for `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.

      Specified by:
        `doFilterInternal` in class `OncePerRequestFilter`
      Throws:
        `ServletException`
        `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` if all conditions match:

      - response status codes in the `2xx` series
      - request method is a GET
      - response Cache-Control header is not set or does not contain a "no-store" directive
      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 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`