掘金 后端 ( ) • 2024-04-27 17:51

问题

最近两天出现了一个很神奇的bug,一个http接口传输文件参数,同样的调用方式,一个服务正常,一个服务文件总是空文件

排查思路,先看日志,因为没有报错,日志很正常,定位代码段,找到造成文件丢失的代码位置

File file = File.createTempFile("temp","." + originalExtension)
写入临时文件内容
params.add("files",new FileSystemResources(file));

代码逻辑是根据文件获取文件地址,获取文件对象写入临时文件夹,转换为FileSystemResources当作http接口入参调用

开始寻找问题,找到服务器上的文件,发现临时文件内容为0kb

查看临时文件权限,排除文件权限问题

打印获取的文件对象长度,排除获取的文件内容为空

卡断点,发现创建临时文件写入这步,文件是有内容的,是被后面的代码覆盖了

最终定位到JSON.toJSONString()

原来我疏忽了一个正常的代码,就是日志,我的日志格式是把内容转换为json输出,用到了fastjson 的JSON.toJSONString()方法

分析总结

FileSystemResource是spring封装的类,其中的FileSystemResource.getOutputStream()

image.png

image.png 可以注意到这里,如果文件不存在则创建文件,如果文件存在则将现有文件截断为0kb

但是JSON.toJSONString(map)这段代码将所有get方法调用了一遍来获取信息

问题就出现在这里,所以JSON.toJSONString()进行打印的时候要注意,重写get方法(也就是不是属性的get方法)的复杂对象不要用