在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();
}
}