java - Spring CommonsRequestLoggingFilter 解决方法来记录请求/响应负载
问题描述
我有一个使用 JSON 作为请求/回复格式的 RESTful API,我想记录客户端发送的有效负载和 API 发送的响应。
(我的 pom.xml 中定义的 Spring Boot 版本是 2.2.1.RELEASE)
Spring 提供了一个非常方便的过滤器来做到这一点:
@Bean
public CommonsRequestLoggingFilter logFilter() {
CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter();
filter.setIncludeQueryString(true);
filter.setIncludePayload(true);
filter.setMaxPayloadLength(10000);
filter.setIncludeHeaders(false);
return filter;
}
但它不起作用:没有记录有效负载!
如果我深入研究扩展类中有趣的部分代码AbstractRequestLoggingFilter.doFilterInternal
:
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
[...]
if (isIncludePayload() && isFirstRequest && !(request instanceof ContentCachingRequestWrapper)) {
requestToUse = new ContentCachingRequestWrapper(request, getMaxPayloadLength());
}
[...]
}
它用于ContentCachingRequestWrapper
解决有效负载是 Stream 的事实,因此只能使用一次。
该构造初始化一个 ByteArrayOutputStream 来缓存有效负载:
public ContentCachingRequestWrapper(HttpServletRequest request, int contentCacheLimit) {
super(request);
this.cachedContent = new ByteArrayOutputStream(contentCacheLimit);
this.contentCacheLimit = contentCacheLimit;
}
但它不会将流的内容复制到 var 中,cachedContent
除非您调用方法writeRequestParametersToCachedContent
(getParameterValues
例如通过),但这种情况从来都不是这样,因此流保持为 0。
问题:
为什么流没有在构造函数中复制?
是否有一种解决方法可以不因为
ContentCachingRequestWrapper
有问题而重新实现所有内容?
谢谢
解决方案
推荐阅读
- c# - 如何在 C# 中使用 WorksheetFunction.CountIf?
- flutter - Flutter - 在日期时间选择器时间轴中仅显示月份
- rust - Rust:用函数修改引用的引用对象;这是否包含UB?
- sql - 记录特定用户访问的单个数据库 postgresql 中所有表的查询
- c# - 如何在 WPF 中的控件上使用 Light?
- python - 对部分多索引数据框的熊猫操作
- javascript - 从 JS 动态创建 svg 不适用于剪辑路径
- c++ - 新行上的 clang-format columnlimit 返回类型
- python-3.x - 升级到 Mac OS 11 (Big Sur) 后,OpenCV 无法与 PyCharm 一起使用
- javascript - 使用 Object.entries 遍历对象