在Spring Boot中使用Filter来记录请求和响应

  |   评论   |   浏览

背景

在Spring Boot中使用Filter来记录请求和响应

原理

默认的流是不支持重复读取的。这里可以使用下面这两个类,在读取的时候,同时会复制记录。

使用 ContentCachingRequestWrapperContentCachingResponseWrapper 来记录请求。

方法

package io.springcloud.demo.filter; import java.io.IOException; import java.nio.charset.StandardCharsets; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; import org.springframework.web.util.ContentCachingRequestWrapper; import org.springframework.web.util.ContentCachingResponseWrapper; import lombok.extern.slf4j.Slf4j; @Component @WebFilter(urlPatterns = "/*") @Order(-999) @Slf4j public class AccessLogFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { ContentCachingRequestWrapper req = new ContentCachingRequestWrapper(request); ContentCachingResponseWrapper resp = new ContentCachingResponseWrapper(response); // Execution request chain filterChain.doFilter(req, resp); // Get Cache byte[] requestBody = req.getContentAsByteArray(); byte[] responseBody = resp.getContentAsByteArray(); log.info("request body = {}", new String(requestBody, StandardCharsets.UTF_8)); log.info("response body = {}", new String(responseBody, StandardCharsets.UTF_8)); // Finally remember to respond to the client with the cached data. resp.copyBodyToResponse(); } }

参考

  1. How to Record Request and Response Bodies in Sping Boot Applications