Class BodyCapturingFilter

  • All Implemented Interfaces:
    Filter

    public abstract class BodyCapturingFilter
    extends Object
    implements Filter
    A filter that captures request and response bodies. When the request body is fully read, onBodyCaptured(BodyCapturingRequest) is called. When the response is complete, onBodyCaptured(BodyCapturingResponse, HttpServletRequest) is called. Both methods can be overridden to perform the necessary logic, for example logging the request and/or response.

    If the request body is not fully read, by default onBodyCaptured(BodyCapturingRequest) is never called. This can be the case if none of the downstream filters and servlets fully consumes the request's body. This is the default setting for some frameworks. For instance, some JSON parsers stop reading as soon as the root object's closing curly brace is encountered. Ideally the framework should be configured to consume all content (for custom filters and servlets ensureBodyConsumed(HttpServletRequest, boolean) is available). If that's not possible, the following initialization parameters are available to attempt to ensure onBodyCaptured(BodyCapturingRequest) is still called:

    Supported initialization parameters
    Name Type Description Default
    considerRequestReadAfterContentLength boolean true to consider the request body as fully read once the number of bytes or characters specified in the Content-Length header has been reached. false
    ensureRequestBodyConsumed boolean true to ensure that the request body is consumed. This is be done after the response has been completed. This means that if the request body has not been consumed already, onBodyCaptured(BodyCapturingRequest) will be called just before onBodyCaptured(BodyCapturingResponse, HttpServletRequest) is called. false
    In addition, the following initialization parameters are available to tweak the amount of storage needed to capture request and response bodies:
    Supported initialization parameters
    Name Type Description Default
    initialRequestCapacity int The initial capacity for the buffer used for capturing a request's body; not negative. May be overridden on a per-request basis by initialRequestCapacity(HttpServletRequest). 32
    initialRequestCapacityFromContentLength boolean true to use the request's content length for the initial capacity. If true, the initialRequestCapacity initialization parameter is ignored. false
    requestLimit int The limit for the number of bytes or characters of a request's body to capture; not negative. May be overridden on a per-request basis by requestLimit(HttpServletRequest). Integer.MAX_VALUE
    initialResponseCapacity int The initial capacity for the buffer used for capturing a response's body; not negative. May be overridden on a per-request basis by initialResponseCapacity(HttpServletRequest). 32
    responseLimit int The limit for the number of bytes or characters of a response's body to capture; not negative. May be overridden on a per-request basis by responseLimit(HttpServletRequest). Integer.MAX_VALUE

    Note that captureBody(HttpServletRequest) can be used to completely turn off capturing a request's body; if this is the case, onBodyCaptured(BodyCapturingRequest) is called immediately. To turn off capturing a response's body, set its limit to 0 and ignore any call to onLimitReached(BodyCapturingResponse, HttpServletRequest).

    Author:
    Rob Spoor
    • Constructor Detail

      • BodyCapturingFilter

        public BodyCapturingFilter()
    • Method Detail

      • destroy

        public void destroy()
        Specified by:
        destroy in interface Filter
      • captureBody

        protected boolean captureBody​(HttpServletRequest request)
        Returns whether or not the body of a request should be captured.

        If this method returns false, then onBodyCaptured(BodyCapturingRequest) will be called immediately with a request for which the body will not have been captured. This prevents unnecessary capturing of the request body when it's not needed, e.g. because there is no request body.

        This implementation returns false if either of the following condition holds:

        • The considerRequestReadAfterContentLength initialization parameter is true and the request's content length is 0.
        • hasNoBody(String) returns true.
        Parameters:
        request - The request for which to return whether or not the body should be captured.
        Returns:
        true if the request's body should be captured, or false otherwise.
      • hasNoBody

        protected boolean hasNoBody​(String method)
        Returns whether or not an HTTP method has no body. This method is used in captureBody(HttpServletRequest) to prevent capturing the request body when it's certain that there is no request body.

        This implementation returns whether or not the method is one of GET, DELETE, OPTIONS or HEAD.

        Parameters:
        method - The method to check.
        Returns:
        true if the HTTP method has no body, or false otherwise.
      • onLimitReached

        protected void onLimitReached​(BodyCapturingFilter.BodyCapturingRequest request)
        Called when the capture limit for a request's body is reached. This method will be called at most once for each request.

        This implementation does nothing.

        Parameters:
        request - The request for which the capture limit is reached.
      • onBodyCaptured

        protected void onBodyCaptured​(BodyCapturingFilter.BodyCapturingRequest request)
        Called when a request's body has been read. This will be the case either if the request's body has been fully consumed, or if its input stream or reader is closed. This method will be called at most once for each request.

        If all downstream filters and servlets fail to (completely) consume the request, this method will not be called by default. Set initialization parameter ensureRequestBodyConsumed to true to ensure that the request body is always consumed. This will be done after the response has been completed (but before onBodyCaptured(BodyCapturingResponse, HttpServletRequest) is called).

        This implementation does nothing.

        Parameters:
        request - The request for which the body has been read.
      • onLimitReached

        protected void onLimitReached​(BodyCapturingFilter.BodyCapturingResponse response,
                                      HttpServletRequest request)
        Called when the capture limit for a response's body is reached. This method will be called at most once for each response, unless ServletResponse.reset() or ServletResponse.resetBuffer() is called on the response. For each call to either method, this method may be called at most once again.

        This implementation does nothing.

        Parameters:
        response - The response for which the capture limit is reached.
        request - The request that lead to the response. This is provided to provide access to any request attributes.
      • initialRequestCapacity

        protected int initialRequestCapacity​(HttpServletRequest request)
        Returns the initial capacity for the buffer used for capturing a request's body. This implementation will return the given request's content length if the initialRequestCapacityFromContentLength initialization parameter is set to true and the request has a content length defined. Otherwise it will return the value of the initialRequestCapacity initialization parameter. If that's not given, 32 will be used.

        This method can be overridden to return something else depending on the request, for example based on the content type.

        Parameters:
        request - The request for which to return the initial buffer capacity.
        Returns:
        The initial buffer capacity for the given request.
      • requestLimit

        protected int requestLimit​(HttpServletRequest request)
        Returns the limit for the number of bytes or characters of a request's body to capture. This implementation will return the value of the requestLimit initialization parameter.

        This method can be overridden to return something else depending on the request, for example based on the content type.

        Parameters:
        request - The request for which to return the capture limit.
        Returns:
        The capture limit for the given request.
      • initialResponseCapacity

        protected int initialResponseCapacity​(HttpServletRequest request)
        Returns the initial capacity for the buffer used for capturing a response's body. This implementation will return the value of the initialResponseCapacity initialization parameter. If that's not given, 32 will be used.

        This method can be overridden to return something else depending on the request, for example based on the path. Since this method is called before the response is populated, the response cannot be used and is therefore not provided.

        Parameters:
        request - The request that leads to the response for which to return the initial buffer capacity.
        Returns:
        The initial buffer capacity for the response to the given request.
      • responseLimit

        protected int responseLimit​(HttpServletRequest request)
        Returns the limit for the number of bytes or characters of a response's body to capture. This implementation will return the value of the responseLimit initialization parameter.

        This method can be overridden to return something else depending on the request, for example based on the path. Since this method is called before the response is populated, the response cannot be used and is therefore not provided.

        Parameters:
        request - The request that leads to the response for which to return the capture limit.
        Returns:
        The capture limit for the response to the given request.