Class CachingHttpServletRequest

java.lang.Object
jakarta.servlet.ServletRequestWrapper
jakarta.servlet.http.HttpServletRequestWrapper
org.apache.juneau.rest.server.util.CachingHttpServletRequest
All Implemented Interfaces:
jakarta.servlet.http.HttpServletRequest, jakarta.servlet.ServletRequest

public class CachingHttpServletRequest extends jakarta.servlet.http.HttpServletRequestWrapper
Wraps an HttpServletRequest and tees a bounded copy of the request body into memory for debug logging.

Unlike a fully-buffering wrapper, this captures at most a configured cap (default 8 KB) of the body while passing the full stream through to the handler untouched. The total number of bytes read is tracked so a truncation marker can be rendered. Memory stays bounded even for large uploads.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    static final int
    Default body capture cap, in bytes (8 KB).

    Fields inherited from interface jakarta.servlet.http.HttpServletRequest

    BASIC_AUTH, CLIENT_CERT_AUTH, DIGEST_AUTH, FORM_AUTH
  • Constructor Summary

    Constructors
    Modifier
    Constructor
    Description
    protected
    CachingHttpServletRequest(jakarta.servlet.http.HttpServletRequest req, int cap)
    Constructor.
  • Method Summary

    Modifier and Type
    Method
    Description
    byte[]
    Returns the captured (possibly truncated) request body bytes.
    jakarta.servlet.ServletInputStream
     
    Returns a character-stream tee over the same underlying byte stream captured by getInputStream().
    long
    Returns the total number of body bytes read so far, including any bytes beyond the capture cap.
    wrap(jakarta.servlet.http.HttpServletRequest req)
    Wraps the specified request inside a CachingHttpServletRequest if it isn't already, using the default cap.
    wrap(jakarta.servlet.http.HttpServletRequest req, int cap)
    Wraps the specified request inside a CachingHttpServletRequest if it isn't already.

    Methods inherited from class jakarta.servlet.http.HttpServletRequestWrapper

    authenticate, changeSessionId, getAuthType, getContextPath, getCookies, getDateHeader, getHeader, getHeaderNames, getHeaders, getHttpServletMapping, getIntHeader, getMethod, getPart, getParts, getPathInfo, getPathTranslated, getQueryString, getRemoteUser, getRequestedSessionId, getRequestURI, getRequestURL, getServletPath, getSession, getSession, getTrailerFields, getUserPrincipal, isRequestedSessionIdFromCookie, isRequestedSessionIdFromURL, isRequestedSessionIdValid, isTrailerFieldsReady, isUserInRole, login, logout, newPushBuilder, upgrade

    Methods inherited from class jakarta.servlet.ServletRequestWrapper

    getAsyncContext, getAttribute, getAttributeNames, getCharacterEncoding, getContentLength, getContentLengthLong, getContentType, getDispatcherType, getLocalAddr, getLocale, getLocales, getLocalName, getLocalPort, getParameter, getParameterMap, getParameterNames, getParameterValues, getProtocol, getProtocolRequestId, getRemoteAddr, getRemoteHost, getRemotePort, getRequest, getRequestDispatcher, getRequestId, getScheme, getServerName, getServerPort, getServletConnection, getServletContext, isAsyncStarted, isAsyncSupported, isSecure, isWrapperFor, isWrapperFor, removeAttribute, setAttribute, setCharacterEncoding, setCharacterEncoding, setRequest, startAsync, startAsync

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

    Methods inherited from interface jakarta.servlet.ServletRequest

    getAsyncContext, getAttribute, getAttributeNames, getCharacterEncoding, getContentLength, getContentLengthLong, getContentType, getDispatcherType, getLocalAddr, getLocale, getLocales, getLocalName, getLocalPort, getParameter, getParameterMap, getParameterNames, getParameterValues, getProtocol, getProtocolRequestId, getRemoteAddr, getRemoteHost, getRemotePort, getRequestDispatcher, getRequestId, getScheme, getServerName, getServerPort, getServletConnection, getServletContext, isAsyncStarted, isAsyncSupported, isSecure, removeAttribute, setAttribute, setCharacterEncoding, setCharacterEncoding, startAsync, startAsync
  • Field Details

  • Constructor Details

    • CachingHttpServletRequest

      protected CachingHttpServletRequest(jakarta.servlet.http.HttpServletRequest req, int cap)
      Constructor.
      Parameters:
      req - The request being wrapped. Must not be null.
      cap - The maximum number of body bytes to capture.
  • Method Details

    • wrap

      public static CachingHttpServletRequest wrap(jakarta.servlet.http.HttpServletRequest req)
      Wraps the specified request inside a CachingHttpServletRequest if it isn't already, using the default cap.
      Parameters:
      req - The request to wrap. Must not be null.
      Returns:
      The wrapped request.
    • wrap

      public static CachingHttpServletRequest wrap(jakarta.servlet.http.HttpServletRequest req, int cap)
      Wraps the specified request inside a CachingHttpServletRequest if it isn't already.
      Parameters:
      req - The request to wrap. Must not be null.
      cap - The maximum number of body bytes to capture.
      Returns:
      The wrapped request.
    • getContent

      public byte[] getContent()
      Returns the captured (possibly truncated) request body bytes.
      Returns:
      The captured body bytes (at most the configured cap). Never null; empty if the body was not read.
    • getTotalLength

      public long getTotalLength()
      Returns the total number of body bytes read so far, including any bytes beyond the capture cap.
      Returns:
      The total body length in bytes.
    • getInputStream

      public jakarta.servlet.ServletInputStream getInputStream() throws IOException
      Specified by:
      getInputStream in interface jakarta.servlet.ServletRequest
      Overrides:
      getInputStream in class jakarta.servlet.ServletRequestWrapper
      Throws:
      IOException
    • getReader

      Returns a character-stream tee over the same underlying byte stream captured by getInputStream().

      A handler that reads the request body through getReader() instead of getInputStream() would otherwise bypass capture entirely — the default ServletRequestWrapper.getReader() delegates straight to the wrapped request. This override routes the reader through the tee'd stream so both access styles are captured identically.

      Specified by:
      getReader in interface jakarta.servlet.ServletRequest
      Overrides:
      getReader in class jakarta.servlet.ServletRequestWrapper
      Throws:
      IOException