Why Does My Java Filter Log Requests Twice? The Hidden Implicit Registration Explained
During development of the DCS_FunTester framework a custom servlet filter logged each HTTP request twice because Spring automatically registered an implicit filter with a lowercase bean name, and overriding the filterName resolved the duplicate logging issue.
While building the DCS_FunTester distributed performance‑testing framework, a custom WrappingFilter was created to log HTTP request parameters and response bodies. After migrating the project, the developer noticed that every request appeared twice in the console output.
Observed Duplicate Logs
The console showed pairs of identical log lines such as:
INFO com.funtester.master.common.wapper.WrappingFilter:65 请求:/m/infos,耗时:1 ms,参数:,响应:{"code":0,"data":{}},来源:0:0:0:0:0:0:0:1Because the local tests responded within 1–2 ms, the duplication was initially thought to be a manual repeat, but further inspection confirmed a systematic double logging.
Filter Implementation
@Component
@WebFilter(urlPatterns = "/*", filterName = "WrappingFilter")
public class WrappingFilter implements Filter {
private static Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
String ipAddress = getIpAddress(req);
HttpServletResponse resp = (HttpServletResponse) response;
ResponseWrapper responseWrapper = new ResponseWrapper(resp);
RequestWrapper requestWrapper = new RequestWrapper(req);
String url = requestWrapper.getRequestURI();
String queryArgs = requestWrapper.getQueryString();
queryArgs = queryArgs == null ? DecodeEncode.unicodeToString(requestWrapper.getBody()) : queryArgs;
String method = requestWrapper.getMethod();
long start = Time.getTimeStamp();
chain.doFilter(requestWrapper == null ? request : requestWrapper, responseWrapper);
long end = Time.getTimeStamp();
byte[] bytes = responseWrapper.getContent();
String respContent = new String(bytes, Constant.UTF_8);
logger.info("请求:{},耗时:{} ms,参数:{},响应:{},来源:{}", url, end - start, queryArgs, respContent, ipAddress);
response.getOutputStream().write(respContent.getBytes(Constant.UTF_8));
}
}Root Cause Investigation
The developer first suspected the log4j2.xml configuration, but after verifying the file the issue persisted. Repeated service restarts and GET requests still produced paired log entries, with only the response time differing.
Hidden Implicit Filter Registration
Spring Boot automatically registers a filter bean using the class name with a lowercase first letter (e.g., wrappingFilter) when @WebFilter is present. Because the explicit registration used filterName = "WrappingFilter", the framework ended up creating two filter instances: the explicit one and the implicit one. Both processed each request, resulting in duplicate log statements.
Solution
Override the implicit registration by setting the filter name to the lowercase bean name: filterName = "wrappingFilter" Doing so ensures only a single filter instance handles the request, eliminating the duplicated logs.
Additional Note
If the implicit filter is not overridden, its urlPatterns default to /*, meaning every endpoint is processed by the hidden filter as well, which can unintentionally broaden the scope of logging or other filter logic.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
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.
