Backend Development 11 min read

Spring Boot Request Logging, Request/Response Wrappers, OncePerRequestFilter, and AOP Utility Classes

This article explains how Spring Boot's built‑in logging filter, request and response caching wrappers, the OncePerRequestFilter base class, and AOP helper classes such as AopContext, AopUtils, and ReflectionUtils can be configured and used to record, modify, and monitor HTTP traffic and simplify proxy‑based programming.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Spring Boot Request Logging, Request/Response Wrappers, OncePerRequestFilter, and AOP Utility Classes

Spring Boot provides a set of built‑in utilities that help developers efficiently log, wrap, and process HTTP requests and responses, as well as simplify AOP‑related programming.

1. Request Data Logging

Spring Boot includes AbstractRequestLoggingFilter , whose commonly used implementation is CommonsRequestLoggingFilter . By registering this filter, developers can record query strings, payloads, headers, and client information.

@Configuration
public class RequestLoggingConfig {
    @Bean
    public CommonsRequestLoggingFilter logFilter() {
        CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter();
        filter.setIncludeQueryString(true);
        filter.setIncludePayload(true);
        filter.setIncludeHeaders(true);
        filter.setIncludeClientInfo(true);
        filter.setAfterMessagePrefix("REQUEST DATA-");
        return filter;
    }
}

Set the logger level to DEBUG for org.springframework.web.filter.CommonsRequestLoggingFilter to see detailed request logs.

2. Request/Response Wrappers

What are they?

Spring provides ContentCachingRequestWrapper and ContentCachingResponseWrapper to cache the request body and response body, allowing multiple reads and post‑processing.

Request Wrapper

ContentCachingRequestWrapper : caches the input stream so the body can be read repeatedly (e.g., for logging).

Response Wrapper

ContentCachingResponseWrapper : caches the output stream so the response can be modified before it is sent to the client.

Typical Use Cases

Request logging (headers, parameters, body).

Modifying request data before it reaches controllers.

Modifying response content (adding headers, signatures, etc.).

Performance testing by caching I/O.

Example: Request Wrapper Filter

import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class RequestWrapperFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request);
        // Example: read body for logging
        byte[] body = requestWrapper.getContentAsByteArray();
        // ...process body...
        filterChain.doFilter(requestWrapper, response);
    }
}

Example: Response Wrapper Filter

import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class ResponseWrapperFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        ContentCachingResponseWrapper responseWrapper = new ContentCachingResponseWrapper(response);
        filterChain.doFilter(request, responseWrapper);
        // Example: add a custom header after processing
        byte[] body = responseWrapper.getContentAsByteArray();
        responseWrapper.setHeader("X-Signature", "some-signature");
        responseWrapper.copyBodyToResponse();
    }
}

3. OncePerRequestFilter

OncePerRequestFilter is a Spring base class that guarantees a filter runs only once per request, even when the request is forwarded or included.

Single execution prevents duplicate processing.

Built‑in support for request/response wrappers.

Reduces boilerplate code.

Easy to extend by overriding doFilterInternal .

Typical Scenarios

Request logging without duplicate entries.

Pre‑processing or modifying request data.

Post‑processing response data (e.g., adding headers, signatures).

Security checks that should run only once.

Performance monitoring.

Centralized exception handling.

4. AOP Helper Classes ("Three‑Piece Set")

AopContext

Provides access to the current proxy and target objects. Common methods:

getTargetObject() – retrieve the underlying bean.

currentProxy() – obtain the current proxy, useful for self‑invocation scenarios.

public void noTransactionTask(String keyword) {
    ((YourClass) AopContext.currentProxy()).transactionTask(keyword);
}

@Transactional
void transactionTask(String keyword) {
    // business logic
    System.out.println(keyword);
}

AopUtils

Utility class for AOP‑related operations such as detecting proxy type.

getTargetObject(Object proxy)

isJdkDynamicProxy(Object obj)

isCglibProxy(Object obj)

if (AopUtils.isCglibProxy(myService)) {
    System.out.println("This is a CGLIB proxy");
}

ReflectionUtils

Convenient wrapper around Java reflection, offering methods to make fields accessible, read/write fields, and invoke methods.

makeAccessible(Field field)

getField(Field field, Object target)

invokeMethod(Method method, Object target, Object... args)

Field field = ReflectionUtils.findField(ExampleBean.class, "mapAttribute");
ReflectionUtils.makeAccessible(field);
Object value = ReflectionUtils.getField(field, bean);
System.out.println(value);

These built‑in classes simplify common AOP and reflection tasks in Spring applications.

JavaAOPSpring BootOncePerRequestFilterRequest LoggingRequest WrapperResponse Wrapper
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.