惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
J
Java Code Geeks
Blog — PlanetScale
Blog — PlanetScale
F
Fortinet All Blogs
腾讯CDC
大猫的无限游戏
大猫的无限游戏
Jina AI
Jina AI
WordPress大学
WordPress大学
雷峰网
雷峰网
小众软件
小众软件
D
DataBreaches.Net
V
Visual Studio Blog
博客园 - Franky
IT之家
IT之家
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
B
Blog RSS Feed
博客园 - 聂微东
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Microsoft Security Blog
Microsoft Security Blog
G
Google Developers Blog
云风的 BLOG
云风的 BLOG

Hsu Yeung 的博客

三圣花市 | Hsu Yeung 的博客 网站支持 Live Photo 图片展示 | Hsu Yeung 的博客 梦 | Hsu Yeung 的博客 周末午餐 | Hsu Yeung 的博客 张家界 | Hsu Yeung 的博客 话剧《寻她芳踪·张爱玲》 | Hsu Yeung 的博客 博客自动生成文章目录 | Hsu Yeung 的博客 灭螂行动! | Hsu Yeung 的博客 张靓颖成都演唱会 | Hsu Yeung 的博客 最近对博客做的一些微调总结 | Hsu Yeung 的博客 Windows 上安装 Lua | Hsu Yeung 的博客 网站支持展示 B 站 iframe 视频 SpringBoot 中使用 RedisTemplate 存取整数值的坑 | Hsu Yeung 的博客 SQL JOIN 中 ON 与 WHERE 的区别 值得记录的一些工作近况 | Hsu Yeung 的博客 周传雄成都演唱会 | Hsu Yeung 的博客 并行操作导致获取数据库连接超时 | Hsu Yeung 的博客 风信子 | Hsu Yeung 的博客 Linux 安装并配置 Nginx | Hsu Yeung 的博客 使用 logrotate 切割 nginx 日志 郁金香土培结果 | Hsu Yeung 的博客 MySQL LEFT JOIN 右表有多条数据但只取最新的一条 | Hsu Yeung 的博客 获取数据库锁等待超时问题 | Hsu Yeung 的博客 从零开始挑选相机 | Hsu Yeung 的博客 郁金香 | Hsu Yeung 的博客 我的第一束花 | Hsu Yeung 的博客 快乐的一周 | Hsu Yeung 的博客 重庆,来了 | Hsu Yeung 的博客 散步 | Hsu Yeung 的博客 Git 工作区、暂存区、版本库之间的关系 | Hsu Yeung 的博客
AOP 记录请求参数时序列化异常问题 | Hsu Yeung 的博客
2023-10-10 · via Hsu Yeung 的博客

今天在 test 环境部署接口后,群里前端同事说登录页的图形验证码获取失败了。看日志报错信息是:getOutputStream() has already been called for this response. 再看代码,也没看出来代码哪里有问题,之前就是好好的,怎么我部署一下就出问题了。

本地启动调用接口将问题复现后,发现是下午同事提交的代码导致的。同事在项目里加了一个 AOP 来记录所有接口的请求参数,其中记录请求参数的代码如下:

// 接口请求参数
Object[] args = joinPoint.getArgs();
// 报错的代码
extraInfo.put("args", JSONArray.toJSONString(logArgs));

断点查看这个 args 变量的值

default-alt

里面有一个 HeaderWriterResponse 对象,查看这个对象的定义

default-alt

可以发现其实这个参数就是验证码接口中的 HttpServletResponse response 参数:

default-alt

其实不光是 HttpServletResponse 对象会导致序列化报错,HttpServletRequest 也会导致报错,只不过报错信息不一样。解决办法很简单,只需要将这两种类型的参数从 args 中过滤掉即可,本身这两种类型的参数对我们的日志记录也没有任何意义。

// 接口请求参数
Object[] args = joinPoint.getArgs();
List<Object> logArgs = Arrays
                .stream(args)
                .filter(arg -> (!(arg instanceof HttpServletRequest) && !(arg instanceof HttpServletResponse)))
                .collect(Collectors.toList());
extraInfo.put("args", JSONArray.toJSONString(logArgs));