Master Spring Boot Request Logging, Wrappers, and AOP Utilities in One Guide
This article explains how to use Spring Boot's built‑in request logging, request/response wrappers, OncePerRequestFilter, and AOP utility classes such as AopContext, AopUtils, and ReflectionUtils, providing configuration snippets and practical code examples for backend developers.
Spring Boot provides many built‑in utilities that help developers efficiently develop and maintain applications.
1. Request Data Logging
Spring Boot offers a built‑in logging solution via
AbstractRequestLoggingFilter. The commonly used implementation is
CommonsRequestLoggingFilter, which can record request parameters, body, headers, and client information.
Enable it with a simple configuration:
<code>@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;
}
}
</code>Set the log level to DEBUG to capture detailed request information:
<code>logging.level.org.springframework.web.filter.CommonsRequestLoggingFilter=DEBUG
</code>2. Request/Response Wrappers
2.1 What are request and response wrappers
In Spring Boot, request and response wrappers enhance the native
HttpServletRequestand
HttpServletResponseobjects, allowing interception and modification of data during processing.
Request Wrapper
ContentCachingRequestWrapper: Caches the request input stream so the body can be read multiple times.
Response Wrapper
ContentCachingResponseWrapper: Caches the response output stream, enabling modification before the response is sent.
2.2 Usage Scenarios
Request logging.
Modifying request data before it reaches controllers.
Modifying response content before it is sent to the client.
Performance testing without affecting network I/O.
2.3 Example Code
Request Wrapper
<code>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);
// Process request data, e.g., log the body
byte[] body = requestWrapper.getContentAsByteArray();
filterChain.doFilter(requestWrapper, response);
}
}
</code>Response Wrapper
<code>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);
// Process response data, e.g., add a signature header
byte[] body = responseWrapper.getContentAsByteArray();
responseWrapper.setHeader("X-Signature", "some-signature");
responseWrapper.copyBodyToResponse();
}
}
</code>The
OncePerRequestFilterbase class ensures the filter runs only once per request lifecycle, preventing duplicate processing.
3. OncePerRequestFilter
3.1 Overview
OncePerRequestFilteris a Spring filter base class that guarantees single execution per request, even when the request is forwarded or included.
Single execution per request lifecycle.
Built‑in support for request and response wrappers.
Simplifies filter code by handling registration and execution.
Easy to extend by overriding
doFilterInternal.
3.2 Typical Use Cases
Request logging without duplicate entries.
Pre‑processing or modifying request data.
Post‑processing or modifying response data.
Security checks such as authentication and authorization.
Wrapping requests and responses for caching.
Performance monitoring.
Centralized exception handling.
4. AOP Utility Classes
4.1 AopContext
AopContextprovides access to the current proxy and target objects. Common methods:
getTargetObject(): Retrieve the target object.
currentProxy(): Retrieve the current proxy.
Example: using
AopContext.currentProxy()to invoke a transactional method from the same class.
<code>public void noTransactionTask(String keyword) {
// Call transactional method via proxy to keep @Transactional effective
((YourClass) AopContext.currentProxy()).transactionTask(keyword);
}
@Transactional
void transactionTask(String keyword) {
try { Thread.sleep(5000); } catch (InterruptedException e) { /* handle */ }
System.out.println(keyword);
}
</code>4.2 AopUtils
AopUtilsoffers static helpers for AOP operations, such as obtaining the target object and checking proxy types.
getTargetObject() isJdkDynamicProxy(Object) isCglibProxy(Object)Example checking for a CGLIB proxy:
<code>if (AopUtils.isCglibProxy(myService)) {
System.out.println("This is a CGLIB proxy object");
}
</code>4.3 ReflectionUtils
ReflectionUtilssimplifies reflection tasks such as making fields accessible, reading field values, and invoking methods.
makeAccessible(Field) getField(Field, Object) invokeMethod(Method, Object, Object...)Example retrieving a private map field:
<code>Field field = ReflectionUtils.findField(ExampleBean.class, "mapAttribute");
ReflectionUtils.makeAccessible(field);
Object value = ReflectionUtils.getField(field, bean);
System.out.println(value);
</code>macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.