曹耘豪的博客

Spring使用Filter打印http请求体和返回体

  1. AOP打印日志的问题
  2. 代码实现
    1. Filter代码
    2. 使用

AOP打印日志的问题

代码实现

Filter代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class RequestLogFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

ContentCachingRequestWrapper cachingRequest = caching(request);
ContentCachingResponseWrapper cachingResponse = caching(response);

long start = System.currentTimeMillis();
try {
filterChain.doFilter(cachingRequest, cachingResponse);
long costMs = System.currentTimeMillis() - start;

byte[] requestBytes = cachingRequest.getContentAsByteArray();
byte[] responseBytes = cachingResponse.getContentAsByteArray();

doLog(cachingRequest, new String(requestBytes, UTF_8), new String(responseBytes, UTF_8), costMs);
} finally {
cachingResponse.copyBodyToResponse();
}

}

protected void doLog(HttpServletRequest request, String requestBody, String responseContent, long costMs) {
String requestURI = request.getRequestURI();
String method = request.getMethod();
log.info("http_log method={} uri={} request_body={} response_content={} cost_ms={}", method, requestURI, requestBody, responseContent, costMs);
}

private static ContentCachingRequestWrapper caching(HttpServletRequest httpServletRequest) {
if (httpServletRequest instanceof ContentCachingRequestWrapper) {
return (ContentCachingRequestWrapper) httpServletRequest;
}
return new ContentCachingRequestWrapper(httpServletRequest);
}

private static ContentCachingResponseWrapper caching(HttpServletResponse httpServletResponse) {
if (httpServletResponse instanceof ContentCachingResponseWrapper) {
return (ContentCachingResponseWrapper) httpServletResponse;
}
return new ContentCachingResponseWrapper(httpServletResponse);
}

}

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
@Configuration
public class WebConfiguration {

@Bean
public FilterRegistrationBean<RequestLogFilter> requestLogFilterFilterRegistrationBean() {
FilterRegistrationBean<RequestLogFilter> registration = new FilterRegistrationBean<>();
registration.setFilter(new RequestLogFilter());
registration.addUrlPatterns("/*"); // 匹配哪些url,配置context-path后的路径
registration.setOrder(0); // 默认优先级是最低,设置为0比大多数高,可以包括Filter
return registration;
}

}
   /