【工作隨手記】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越來越好。

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