JSON序列化導(dǎo)致Long類型被搞成Integer的坑及解決
JSON序列化導(dǎo)致Long類型被搞成Integer的坑
最近遇到一個(gè)錯(cuò)誤,就是某個(gè)字段肯定是Long類型的,通過Map<String,Object>方式轉(zhuǎn)成JSON字符串,然后存到了DB的某個(gè)字段里。
為了Json存儲(chǔ)字,然后反序列化為Map(不是自定義的常規(guī)對(duì)象)
比如某二方為了提供通用的接口能力,將Map<String,Object>的數(shù)據(jù)通過JSON序列化方式緩存然后JSON反序列化拿到Map。
等情況。
用的時(shí)候就通過Key獲取對(duì)象之后直接強(qiáng)轉(zhuǎn)Long,然后類型轉(zhuǎn)換異常。
java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long
上代碼
? ? @Test(expected = ClassCastException.class) ? ? public void testJson() { ? ? ? ? String id = "id"; ? ? ? ? String name = "name"; ? ? ? ? Long idValue = 3000L; ? ? ? ? Map<String, Object> data = new HashMap<>(2); ? ? ? ? data.put(id, idValue); ? ? ? ? data.put(name, "張三"); ? ? ? ? ? Assert.assertEquals(idValue, (Long) data.get(id)); ? ? ? ? String jsonString = JSON.toJSONString(data); ? ? ? ? ? // 反序列化時(shí)Long被轉(zhuǎn)為了Integer ? ? ? ? Map map = JSON.parseObject(jsonString, Map.class); ? ? ? ? Object idObj = map.get(id); ? ? ? ? Assert.assertTrue(idObj instanceof Integer); ? ? ? ? Assert.assertEquals(idValue, (Long) idObj); ? ? }
沒用通過JSON序列化,雖然類型為Object,但是實(shí)際的類型為Long。
序列化為Json時(shí)后,Josn串是沒有 Long類型的,而且反轉(zhuǎn)回來也是Object接收,如果數(shù)字小于Interger的最大值,給轉(zhuǎn)成了Integer!
方案
參見我的 另外一篇文章 JSON 反序列化 Long 變 Integer 或 Double 問題
思考
總之開發(fā)中盡量不要亂用一些對(duì)象屬性轉(zhuǎn)換工具,導(dǎo)致屬性漏掉或者轉(zhuǎn)錯(cuò)。
不要濫用Map或者JSONObject來傳遞參數(shù)。
如果是含Object類型JSON序列化要特別小心上述問題?。?/p>
JSON格式轉(zhuǎn)int/long報(bào)錯(cuò)
現(xiàn)象:通過查庫(mysql)獲取信息,其中有個(gè)字段A的值為int類型的5,然后在前端頁面,把數(shù)據(jù)(json)通過ajax請(qǐng)求到后臺(tái)(在前端頁面A的類型為Number),在后臺(tái)用Map<String, Object>接收json數(shù)據(jù),此時(shí)A的值變?yōu)?.0了,從整型變?yōu)榱烁↑c(diǎn)型。此時(shí)轉(zhuǎn)換成int會(huì)出現(xiàn)類型轉(zhuǎn)換異常。
問題:從前端頁面?zhèn)鬟f過來的json串,后臺(tái)能map接收,再利用map的get()方法獲取相應(yīng)的屬性值,這時(shí)當(dāng)屬性類型為int或者long類型時(shí)會(huì)出現(xiàn)轉(zhuǎn)換異常。
解決方法,先將相應(yīng)的屬性轉(zhuǎn)換成Number類型,再調(diào)用Number對(duì)應(yīng)的方法進(jìn)行轉(zhuǎn)換。但有個(gè)地方需要注意,需要先判斷該屬性是否為空再進(jìn)行轉(zhuǎn)換,否則會(huì)出現(xiàn)NullPointerException。
Gson轉(zhuǎn)換導(dǎo)致int轉(zhuǎn)換成double的問題
使用情景:后端返回的json字符串,通過gson處理后,原本是int類型,現(xiàn)在獲取到的是double類型的。
解決:
int i = ((Number)fromJson.get("int")).intValue(); int i = Math.round(Double.parseDouble(fromJson.get("int").toString));
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring之動(dòng)態(tài)注冊(cè)bean的實(shí)現(xiàn)方法
這篇文章主要介紹了Spring之動(dòng)態(tài)注冊(cè)bean的實(shí)現(xiàn)方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-08-08java中的方法重載知識(shí)點(diǎn)總結(jié)
在本篇文章里小編給大家整理了關(guān)于java中的方法重載知識(shí)點(diǎn)總結(jié),有興趣的朋友們可以跟著學(xué)習(xí)參考下。2020-02-02Java實(shí)現(xiàn)DFA算法對(duì)敏感詞、廣告詞過濾功能示例
本篇文章主要介紹了Java實(shí)現(xiàn)DFA算法對(duì)敏感詞、廣告詞過濾功能示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11MyBatis使用注解開發(fā)實(shí)現(xiàn)過程詳解
這篇文章主要介紹了MyBatis使用注解開發(fā)實(shí)現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03