【工作随手记】fastjson date格式化验优先级的问题

本来是一个风和日丽的下午,一个非常简单的改动需求。接口返回的日期类型只需要年月日不需要时分秒。因为我的项目json使用的是fastjson,而不是spring自带的jackson(不要问我为什么)。因为全局格式化为yyyy-MM-dd HH:mmss,于是我愉快的在javabean的属性上加了个注解。

@JSONField(format="yyyy-MM-dd")

本地测试一下,没问题,提交到生产环境,5分钟搞定,完美。

然后就接到产品的电话,改动呢?

我登上去看了一下,唉,没改到啊,日期还是带了时分秒。为了保持我的英明形象(并没有),使用sql格式化,java用string接收返回前端,间接成功处理。

但是原来的问题还是没解决。bug。如果是其它组件我可能不会这么想,但这可是fastjson.
有个笑话这么说的:

大爷:我算术很快。
记者:1234234乘以23523等于多少?
大爷:等于78!
记者:?????
大爷:你就说快不快吧?!
我觉得用来形容fastjson也很合适,你不知道它可能会从哪里给你温柔一击。

既然怀疑是两个系统导致的问题,那么就在idea里模拟一下linux系统。在
VM options 添加 -Dos.name=linux

启动,没有复现bug.

这只是简单的一个设置环境变量为linux,并不能完全模拟linux环境。

于是我想到了远程调试。
一阵操作猛如虎,远程调试倒是能进断点,只是断点进不了第三方jar包的源码。等于白搞。

后来把fastjson的源码拉下来,在关键的JSONSerializer#writeWithFormat方法里添加了一些日志,重新打包,覆盖测试环境的jar包,模拟远程调试。
然后发现测试环境lib目录,fastjson包居然有两个版本1.2.1.2.531.2.83?!

WTF?

我完全搞忘了为什么会有两个版本的包,或许是最初开发阶段搞出来的,自己坑自己?

我隐隐约约有了思路,将高版本删除,留下低版本,成功在本地环境复现了BUG。

应该就是这个原因,高版本里加了注释。

/**
* #1868 为了区分全局配置(FastJsonConfig)的日期格式配置以及toJSONString传入的日期格式配置
* 建议使用以下调整:
* 1. dateFormatPattern、dateFormat只作为toJSONString传入配置使用;
* 2. 新增fastJsonConfigDateFormatPattern,用于存储通过(FastJsonConfig)配置的日期格式
*/
粒度最小的配置应该优先级最高,而在低版本里却恰恰相反,所以导致了这个bug。

更多的来龙去脉可以去看官方的PR描述.

解决问题的关键代码:

所以,只要把版本升级到1.2.55以上版本,且没有其它多余的版本,即可避免上述问题。

后记:
发现fastjson源码里面的一些小槽点,比如在catch块里面做逻辑处理。这是非常影响性能的。

在阿里巴巴java开发规范当中也有这样的强制规定:

当然一款广泛使用的开源软件,如果拿着放大镜总是能找出很多问题。我们是不是一款优秀的开源软件,更应该看大的框架,架构思想。总体来说,fastjson至少值得我去学习。也祝愿fastjson2越来越好。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章