今天在 test 环境部署接口后,群里前端同事说登录页的图形验证码获取失败了。看日志报错信息是:getOutputStream() has already been called for this response. 再看代码,也没看出来代码哪里有问题,之前就是好好的,怎么我部署一下就出问题了。
本地启动调用接口将问题复现后,发现是下午同事提交的代码导致的。同事在项目里加了一个 AOP 来记录所有接口的请求参数,其中记录请求参数的代码如下:
// 接口请求参数
Object[] args = joinPoint.getArgs();
// 报错的代码
extraInfo.put("args", JSONArray.toJSONString(logArgs));
断点查看这个 args
变量的值
里面有一个 HeaderWriterResponse
对象,查看这个对象的定义
可以发现其实这个参数就是验证码接口中的 HttpServletResponse response
参数:
其实不光是 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));
1 条评论
感谢分享