在用FastJson序列數(shù)據(jù)化轉(zhuǎn)換時踩坑經(jīng)驗

之前一直是用Gson做數(shù)據(jù)序列化,后來換工作后新公司是用fastJson做序列化的瘦锹,在做網(wǎng)絡(luò)框架優(yōu)化后,不定時的會拋出JsonObject can't covert to **** 異常,各種排查后發(fā)現(xiàn)是fastJson的問題,下面一步一步來分析:

原始json數(shù)據(jù):

//登錄前
{"code":200,"msg":"成功","data":[]}
//登錄后
{"code":200,"msg":"成功","data":{"count":0}}

解析json代碼:

static CommonResponse responseConvert(String json, Type clz){
           JSONObject object = new JSONObject(json);
           String data = object.optString(DATA);
           if(TextUtils.isEmpty(data) || "[]".equals(data) || "{}".equals(data) ){
            CommonResponse resp =  JSON.parseObject(json, CommonResponse.class);
           ....
           return resp;
           }else{
           return JSON.parseObject(json,clz)
           }
}

分析原因:

從代碼上來看應(yīng)該沒問題怠苔,看不出什么問題,首先判斷json的data字段是否為空或是否為空數(shù)組仪糖,如果是空則使用默認(rèn)的CommonResponse類去解析嘀略,如果不為空則使用CommonResponse<T>泛型的方式去解析,如果data字段一直為空或一直不為空都不會有問題乓诽,但如果從空變成有數(shù)據(jù)后就出現(xiàn)了上面的異常,通過查看fastJson源碼才發(fā)現(xiàn)問題所在:
ParserConfig.Java

public ObjectDeserializer getDeserializer(Type type) {
     ...省略無關(guān)代碼

      if (type instanceof Class<?>) {
          return getDeserializer((Class<?>) type, type);
      }
      if (type instanceof ParameterizedType) {
          Type rawType = ((ParameterizedType) type).getRawType();
          if (rawType instanceof Class<?>) {
              return getDeserializer((Class<?>) rawType, type);
          } else {
              return getDeserializer(rawType);
          }
      }
      return JavaObjectDeserializer.instance;
  }

通過源碼可以看到咒程,首先判斷參數(shù)type是否為Class鸠天,如果是則進入getDeserializer方法,如果不是則繼續(xù)判斷參數(shù)是否為泛型帐姻,getRawType是獲取泛型類型稠集,如果泛型里面沒有再嵌套泛型了則也進入getDeserializer方法,如果還有則進行遞歸調(diào)用饥瓷,直到拿到最里面泛型為止剥纷,繼續(xù)看getDeserializer方法:

public ObjectDeserializer getDeserializer(Class<?> clazz, Type type) {
       ...省略無關(guān)代碼
        if (type instanceof WildcardType || type instanceof TypeVariable || type instanceof ParameterizedType) {
            derializer = derializers.get(clazz);
        }

        if (derializer != null) {
            return derializer;
        }
        ...省略無關(guān)代碼
        putDeserializer(type, derializer);
        return derializer;
 }

在getDeserializer方法中會先去判斷緩存中是否已存儲這個參數(shù)Class如果有則直接用緩存中的,如果沒有則添加到緩存中呢铆。
 代碼看到這里也就發(fā)現(xiàn)問題所在了晦鞋,原因:首先在第一次解析CommonResponse的時候走的是getDeserializer的第一個if棺克,然后緩存起來這個CommonResponse悠垛,接著在登錄后,data字段數(shù)據(jù)類型發(fā)生了改變娜谊,變成CommonResponse<T>類型确买,所以解析的走的是第二個if,結(jié)果rawType是CommonResponse纱皆,所以直接從緩存中返回了第一次解析的結(jié)果湾趾,這樣就相當(dāng)于丟失了CommonResponse中的泛型<T>,所以導(dǎo)致最后類型轉(zhuǎn)換失敯派獭!

總結(jié)

統(tǒng)一使用泛型類型搀缠,不允許沒有泛型類型的CommonResponse铛楣,如果不能統(tǒng)一泛型類型的,最好換一個Json解析庫胡嘿!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蛉艾,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子衷敌,更是在濱河造成了極大的恐慌勿侯,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缴罗,死亡現(xiàn)場離奇詭異助琐,居然都是意外死亡,警方通過查閱死者的電腦和手機面氓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門兵钮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人舌界,你說我怎么就攤上這事掘譬。” “怎么了呻拌?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵葱轩,是天一觀的道長。 經(jīng)常有香客問我藐握,道長靴拱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任猾普,我火速辦了婚禮袜炕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘初家。我一直安慰自己偎窘,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布笤成。 她就那樣靜靜地躺著评架,像睡著了一般。 火紅的嫁衣襯著肌膚如雪炕泳。 梳的紋絲不亂的頭發(fā)上纵诞,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機與錄音培遵,去河邊找鬼浙芙。 笑死登刺,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的嗡呼。 我是一名探鬼主播纸俭,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼南窗!你這毒婦竟也來了揍很?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤万伤,失蹤者是張志新(化名)和其女友劉穎窒悔,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體敌买,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡简珠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了虹钮。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片聋庵。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖芙粱,靈堂內(nèi)的尸體忽然破棺而出祭玉,到底是詐尸還是另有隱情,我是刑警寧澤春畔,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布攘宙,位于F島的核電站,受9級特大地震影響拐迁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜疗绣,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一线召、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧多矮,春花似錦缓淹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至湾盗,卻和暖如春伏蚊,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背格粪。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工躏吊, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留氛改,地道東北人。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓比伏,卻偏偏與公主長得像胜卤,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子赁项,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理葛躏,服務(wù)發(fā)現(xiàn),斷路器悠菜,智...
    卡卡羅2017閱讀 134,656評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,112評論 25 707
  • 你來人間一趟舰攒,你要看看太陽,和你的心上人李剖,一起走在街上芒率。 ...
    橘子墨野閱讀 164評論 0 2
  • 案主信息:和煦的午后,小鳥在天空溜達(dá)篙顺,魚兒在水中散步偶芍,花兒隨著拂面微風(fēng)的律動在歌唱,我在自己小院的樹下讀書德玫。 分析...
    奶茶干媽閱讀 184評論 0 0