Gson解析空字符串異常的處理

面對一些不規(guī)范的json,我們的gson解析經(jīng)常會拋出各種異常導(dǎo)致app崩潰,這里可以采取一些措施來避免


11月9日更新:
關(guān)于數(shù)組類型的字段解析異常,我嘗試了一些方案,但最后都存在問題,如果大家有好的解決方案,希望能貼在下面.不甚感激.
異常示例=>正常json:

{
    "code":0,
    "msg":"ok",
    "data":[    //約定為數(shù)組
      {
        "id":5638,
        "newsId":5638
      }
      ]
}

異常json:

{
    "code":0,
    "msg":"ok",
    "data":{}    //返回為對象或者空字符串
}

Json異常情況

先來看一個(gè)后臺返回的json
正常情況下json:

{
    "code":0,
    "msg":"ok",
    "data":{
        "id":5638,
        "newsId":5638
    }
}

data部分對應(yīng)的實(shí)體類:

public class JsonBean {
    private int id;
    private int newsId;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getNewsId() {
        return newsId;
    }

    public void setNewsId(int newsId) {
        this.newsId = newsId;
    }
}

異常情況json(后臺數(shù)據(jù)庫newsId字段未查詢到對應(yīng)數(shù)據(jù)):

{
    "code":0,
    "msg":"ok",
    "data":{
        "id":5638,
        "newsId":""
    }
}

這樣Gson在解析時(shí)就會拋出解析錯(cuò)誤的異常,app崩潰,原因是無法將""轉(zhuǎn)化為int

json異常的處理

我們期望在后臺返回的json異常時(shí),也能解析成功,空值對應(yīng)的轉(zhuǎn)換為默認(rèn)值,如:newsId=0;
這里排除掉后臺開發(fā)人員輸出時(shí)給你做矯正,還是得靠自己啊---

我們寫一個(gè)針對int值的類型轉(zhuǎn)換器,需要實(shí)現(xiàn)Gson的JsonSerializer<T>接口和JsonDeserializer<T>,即序列化和反序列化接口

public class IntegerDefault0Adapter implements JsonSerializer<Integer>, JsonDeserializer<Integer> {
    @Override
    public Integer deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
            throws JsonParseException {
        try {
            if (json.getAsString().equals("") || json.getAsString().equals("null")) {//定義為int類型,如果后臺返回""或者null,則返回0
                return 0;
            }
        } catch (Exception ignore) {
        }
        try {
            return json.getAsInt();
        } catch (NumberFormatException e) {
            throw new JsonSyntaxException(e);
        }
    }

    @Override
    public JsonElement serialize(Integer src, Type typeOfSrc, JsonSerializationContext context) {
        return new JsonPrimitive(src);
    }
}

同理Long及Double類型

double=>

public class DoubleDefault0Adapter implements JsonSerializer<Double>, JsonDeserializer<Double> {
    @Override
    public Double deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        try {
            if (json.getAsString().equals("") || json.getAsString().equals("null")) {//定義為double類型,如果后臺返回""或者null,則返回0.00
                return 0.00;
        }
            } catch (Exception ignore) {
        }
        try {
            return json.getAsDouble();
        } catch (NumberFormatException e) {
            throw new JsonSyntaxException(e);
        }
    }

    @Override
    public JsonElement serialize(Double src, Type typeOfSrc, JsonSerializationContext context) {
        return new JsonPrimitive(src);
    }
}

long=>

public class LongDefault0Adapter implements JsonSerializer<Long>, JsonDeserializer<Long> {
    @Override
    public Long deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
        throws JsonParseException {
        try {
            if (json.getAsString().equals("") || json.getAsString().equals("null")) {//定義為long類型,如果后臺返回""或者null,則返回0
                    return 0l;
                }
            } catch (Exception ignore) {
        }
        try {
            return json.getAsLong();
        } catch (NumberFormatException e) {
            throw new JsonSyntaxException(e);
        }
    }

    @Override
    public JsonElement serialize(Long src, Type typeOfSrc, JsonSerializationContext context) {
        return new JsonPrimitive(src);
    }
}

所以使用是這樣的:

return new Retrofit.Builder()
       .client(okHttpClient)//設(shè)置網(wǎng)絡(luò)訪問框架
       .addConverterFactory(GsonConverterFactory.create(buildGson()))//添加json轉(zhuǎn)換框架
       .addCallAdapterFactory(RxJavaCallAdapterFactory.create())//讓Retrofit支持RxJava
       .baseUrl(baseUrl)
       .build();

/**
 * 增加后臺返回""和"null"的處理
 * 1.int=>0
 * 2.double=>0.00
 * 3.long=>0L
 *
 * @return
 */
public static Gson buildGson() {
    if (gson == null) {
        gson = new GsonBuilder()
                .registerTypeAdapter(Integer.class, new IntegerDefault0Adapter())
                .registerTypeAdapter(int.class, new IntegerDefault0Adapter())
                .registerTypeAdapter(Double.class, new DoubleDefault0Adapter())
                .registerTypeAdapter(double.class, new DoubleDefault0Adapter())
                .registerTypeAdapter(Long.class, new LongDefault0Adapter())
                .registerTypeAdapter(long.class, new LongDefault0Adapter())
                .create();
    }
    return gson;
}

再也不會因?yàn)楹笈_json字段為空的情況崩潰了

關(guān)于作者

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末枢劝,一起剝皮案震驚了整個(gè)濱河市赋元,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌哪审,老刑警劉巖饶深,帶你破解...
    沈念sama閱讀 218,122評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件餐曹,死亡現(xiàn)場離奇詭異逛拱,居然都是意外死亡敌厘,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評論 3 395
  • 文/潘曉璐 我一進(jìn)店門朽合,熙熙樓的掌柜王于貴愁眉苦臉地迎上來俱两,“玉大人,你說我怎么就攤上這事曹步∠懿剩” “怎么了?”我有些...
    開封第一講書人閱讀 164,491評論 0 354
  • 文/不壞的土叔 我叫張陵讲婚,是天一觀的道長尿孔。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么活合? 我笑而不...
    開封第一講書人閱讀 58,636評論 1 293
  • 正文 為了忘掉前任雏婶,我火速辦了婚禮,結(jié)果婚禮上白指,老公的妹妹穿的比我還像新娘留晚。我一直安慰自己,他們只是感情好告嘲,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評論 6 392
  • 文/花漫 我一把揭開白布错维。 她就那樣靜靜地躺著,像睡著了一般橄唬。 火紅的嫁衣襯著肌膚如雪赋焕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,541評論 1 305
  • 那天仰楚,我揣著相機(jī)與錄音宏邮,去河邊找鬼。 笑死缸血,一個(gè)胖子當(dāng)著我的面吹牛蜜氨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播捎泻,決...
    沈念sama閱讀 40,292評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼飒炎,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了笆豁?” 一聲冷哼從身側(cè)響起郎汪,我...
    開封第一講書人閱讀 39,211評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎闯狱,沒想到半個(gè)月后煞赢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡哄孤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評論 3 336
  • 正文 我和宋清朗相戀三年照筑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瘦陈。...
    茶點(diǎn)故事閱讀 39,965評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡凝危,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出晨逝,到底是詐尸還是另有隱情蛾默,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評論 5 347
  • 正文 年R本政府宣布捉貌,位于F島的核電站支鸡,受9級特大地震影響冬念,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜牧挣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評論 3 329
  • 文/蒙蒙 一刘急、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧浸踩,春花似錦叔汁、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,894評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至折剃,卻和暖如春另假,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背怕犁。 一陣腳步聲響...
    開封第一講書人閱讀 33,012評論 1 269
  • 我被黑心中介騙來泰國打工边篮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人奏甫。 一個(gè)月前我還...
    沈念sama閱讀 48,126評論 3 370
  • 正文 我出身青樓戈轿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親阵子。 傳聞我的和親對象是個(gè)殘疾皇子思杯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評論 2 355

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

  • 1.概述2.Gson的目標(biāo)3.Gson的性能和擴(kuò)展性4.Gson的使用者5.如何使用Gson 通過Maven來使用...
    人失格閱讀 14,234評論 2 18
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)挠进,斷路器色乾,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • 點(diǎn)擊查看原文 Web SDK 開發(fā)手冊 SDK 概述 網(wǎng)易云信 SDK 為 Web 應(yīng)用提供一個(gè)完善的 IM 系統(tǒng)...
    layjoy閱讀 13,762評論 0 15
  • 這個(gè)文章比較“膚淺”,但是其實(shí)網(wǎng)上對于Fragment切換這么膚淺的事情也甚少有文章說的清楚领突,所以稍微介紹下暖璧。 B...
    聰蔥忙忘閱讀 8,958評論 13 8
  • 徐云霞說道 :“既然胡大哥有祖訓(xùn)在身小弟也不便勉強(qiáng),只是小弟仍有一事相求君旦,還望胡大哥應(yīng)允澎办。” 胡斐說道 :“雖然胡...
    長白居士閱讀 264評論 0 0