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

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


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

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

異常json:

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

Json異常情況

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

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

data部分對應的實體類:

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字段未查詢到對應數(shù)據(jù)):

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

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

json異常的處理

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

我們寫一個針對int值的類型轉(zhuǎn)換器,需要實現(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)//設置網(wǎng)絡訪問框架
       .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;
}

再也不會因為后臺json字段為空的情況崩潰了

關于作者

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容