在Spring Boot中使用Filter来记录请求和响应
背景
在Spring Boot中使用Filter来记录请求和响应
原理
默认的流是不支持重复读取的。这里可以使用下面这两个类,在读取的时候,同时会复制记录。
使用 ContentCachingRequestWrapper
和 ContentCachingResponseWrapper
来记录请求。
方法
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(); } }