1. 程式人生 > >Android Study 之 徹底解決 Gson解析 異常 :com.google.gson.JsonSyntaxException

Android Study 之 徹底解決 Gson解析 異常 :com.google.gson.JsonSyntaxException

LZ-Say:大風呼呼的刮,就好像妖精要來的前奏一樣~

這裡寫圖片描述

前言

開發過程中,App常用的接收引數的時候,幾乎大部分都是以json格式為主,那麼有關解析json的方式有很多,Android端相對來說使用Gson比較多,而在解析過程中,如果你遇到規範的後臺,那你大可放心隨便浪,But,如果遇到神後臺,那麼,呵呵了你就。真的想不到還會出現什麼問題。。。

這裡寫圖片描述

描述問題

實現某個功能,呼叫某個介面,返回如下引數:

{
  "areaName": null,
  "accountId": 138,
  "accountName": null,
  "accountNumber
": null, "msgCode": "", "msg": "", "pname": "趙九勝", "nation": "19701010", "imgUri": null, "phone": "15831345807", "areaCode": "230303", "usedTime": null, "collectionWay": 1, "registTime": null, "createTime": "2017-10-26 06:46:23", "amount": 580, "price": 0, "certificates": null, "certificatesPhotos
": null }

大家仔細觀察下,咋眼一看,也沒啥問題是不?

可在解析的過程中,GG了。。。

趟坑路,超神路

滿懷信心的擼碼,執行,app卻提示瞭如下型別錯誤:

com.google.gson.JsonSyntaxException

上來一看,Json格式錯誤?回頭再仔細看下返回的Json。

有的值為null,有的值為“”

重點結合度孃的意見以及重新回顧Json串時,確定了是由於後臺介面引數返回不規範(也就是設計不合理)導致解析失敗。

這裡寫圖片描述

那麼怎麼解決呢?

其實說白了,就是在轉化解析的過程中對後臺返回Json中不合法的屬性欄位進行有效處理即可。具體直接看下面工具類即可。


import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.internal.LinkedTreeMap;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class GsonUtil {

    /**
     * 實現格式化的時間字串轉時間物件
     */
    private static final String DATEFORMAT_default = "yyyy-MM-dd HH:mm:ss";

    /**
     * 使用預設的gson物件進行反序列化
     *
     * @param json
     * @param typeToken
     * @return
     */
    public static <T> T fromJsonDefault(String json, TypeToken<T> typeToken) {
        Gson gson = new Gson();
        return gson.fromJson(json, typeToken.getType());
    }

    /**
     * json字串轉list或者map
     *
     * @param json
     * @param typeToken
     * @return
     */
    public static <T> T fromJson(String json, TypeToken<T> typeToken) {
        Gson gson = new GsonBuilder()
                // 重寫map的反序列化
                .registerTypeAdapter(new TypeToken<Map<String, Object>>() {
                }.getType(), new MapTypeAdapter()).create();
        return gson.fromJson(json, typeToken.getType());
    }

    /**
     * json字串轉bean物件
     *
     * @param json
     * @param cls
     * @return
     */
    public static <T> T fromJson(String json, Class<T> cls) {
        Gson gson = new GsonBuilder().setDateFormat(DATEFORMAT_default)
                .create();
        return gson.fromJson(json, cls);
    }

    /**
     * 物件轉json
     *
     * @param obj
     * @param format
     * @return
     */
    public static String toJson(Object obj, boolean format) {
        GsonBuilder gsonBuilder = new GsonBuilder();
        //  設定預設時間格式
        gsonBuilder.setDateFormat(DATEFORMAT_default);
        // 新增格式化設定
        if (format) {
            gsonBuilder.setPrettyPrinting();
        }
        Gson gson = gsonBuilder.create();
        return gson.toJson(obj);
    }

    public static class MapTypeAdapter extends TypeAdapter<Object> {

        @Override
        public Object read(JsonReader in) throws IOException {
            JsonToken token = in.peek();
            switch (token) {
                case BEGIN_ARRAY:
                    List<Object> list = new ArrayList<Object>();
                    in.beginArray();
                    while (in.hasNext()) {
                        list.add(read(in));
                    }
                    in.endArray();
                    return list;
                case BEGIN_OBJECT:
                    Map<String, Object> map = new LinkedTreeMap<String, Object>();
                    in.beginObject();
                    while (in.hasNext()) {
                        map.put(in.nextName(), read(in));
                    }
                    in.endObject();
                    return map;
                case STRING:
                    return in.nextString();
                case NUMBER:
                    // 改寫數字的處理邏輯,將數字值分為整型與浮點型。
                    double dbNum = in.nextDouble();
                    // 數字超過long的最大值,返回浮點型別
                    if (dbNum > Long.MAX_VALUE) {
                        return dbNum;
                    }
                    // 判斷數字是否為整數值
                    long lngNum = (long) dbNum;
                    if (dbNum == lngNum) {
                        return lngNum;
                    } else {
                        return dbNum;
                    }
                case BOOLEAN:
                    return in.nextBoolean();
                case NULL:
                    in.nextNull();
                    return null;
                default:
                    throw new IllegalStateException();
            }
        }

        @Override
        public void write(JsonWriter out, Object value) throws IOException {
            // 序列化無需實現
        }

    }

}

呼叫方式如下:

List<SearchResultBean> resultBean = GsonUtil.fromJson(
        GsonUtil.toJson(result.getData(), true),  // 這裡需要將獲取到的json再次進行格式化
        new TypeToken<List<SearchResultBean>>() {
        });

結束

其實 度娘有度孃的好處

開發者 好多包括LZ 都是屬於“百度開發者”但是這點並沒有什麼可傲嬌的

能做的 就是在前行的路上 不斷充實自己 加油 各位夥計們

相關推薦

Android Study 徹底解決 Gson解析 異常 com.google.gson.JsonSyntaxException

LZ-Say:大風呼呼的刮,就好像妖精要來的前奏一樣~ 前言 開發過程中,App常用的接收引數的時候,幾乎大部分都是以json格式為主,那麼有關解析json的方式有很多,Android端相對來說使用Gson比較多,而在解析過程中,如果

GsonConverterFactory封裝Gson解析丟擲 com.google.gson.internal.LinkedTreeMap cannot be cast to XXX

原因在於解析的JSON資料結構為無欄位名稱的二維陣列,解析資料時無法從 com.google.gson.internal.LinkedTreeMap強轉為XXX(標題中的data class),歸根到底就是,當二維陣列均無欄位名稱的時候,第二維資料就無法通過@SerializedName從

Android程式 依賴庫引用Gson 報java.lang.NoClassDefFoundError: com/google/gson/Gson 解決方法

Android 程式所依賴一個Library程式B , B 程式中用到格式化json串,轉換成標準json串的要求 public static String jsonFormatter(String uglyJSONString) { Gson gson = new

Android開發中遇到的json解析異常問題

Ⅰ.前言 昨天在解析後臺返回的json資料時,json資料一直解析失敗,剛開始以為是kotlin的bean類問題 ,因為專案已經逐漸把開發語言從java轉為kotlin,還是第一次使用kotlin寫bean類,但是在將bean類改為java實現後,仍解析失敗

異常com.google.gson.internal.StringMap cannot cast to..原因&解決方案

異常資訊 java.lang.ClassCastException: com.google.gson.internal.StringMap cannot cast to… 異常描述 期望使用

Android Study跳轉自啟動管理頁

LZ-Says:話說現在流氓軟體多不勝數,在反感的同時,我們確實應該從技術的角度去分析,為什麼他們能夠做到所謂的流氓呢?技術不分錯對,關鍵在於使用技術的人去如何運用相關技術~ 前言 話說,最近專案要求軟體自啟動,腦子一想,靜態註冊廣播,監聽使用者

Android Studio徹底刪除專案

Android Studio徹底刪除專案 1.Android Studio徹底刪除Module 當不需要某個Module(工程)時,刪除 在“Project”檢視中選擇需要刪除的module名,此處刪除“app”,點選右鍵,選擇“Open Module S

Gson解析異常,請求大神解惑,感激不盡啊

02-20 21:26:26.118: I/Timeline(21380): Timeline: Activity_launch_request id:com.gupian1999 time:20331559 02-20 21:26:26.348: V/SlidingMen

CDH--徹底解決問題----時鐘異常

第 1 章. NTP伺服器安裝及客戶機配置配置之前要確定時間和現實時間一致,手動配置時間命令sudo date -s "2018-04-18 14:50:02"配置時區https://www.cnblogs.com/dyj0201/p/6440632.html如果已有NTP伺

Android apk執行時錯誤java.lang.NoSuchMethodError: com.google.gson.GsonBuilder.setLenient

最近在Hisi3751V500上移植一個新的專案,在執行gitv牌照方apk的時候提示java.lang.NoSuchMethodError: com.google.gson.GsonBuilder.setLenient 06-03 17:44:28.966 I/dalvikvm( 36

解決hibernate 刪除異常 deleted object would be re-saved by cascade (remove deleted ob

解決辦法: 方法1 刪除Set方的cascade 方法2 解決關聯關係後,再刪除 : 方法3 在many-to-one方增加cascade 但值不能是none 以one-To-many為例: 1.如果Many端存在於One端的集合中,直接刪除Many,就會丟擲"deleted object would be

使用GSON丟擲com.google.gson.stream.MalformedJsonException異常

今天在用GSON解析json資料的時候,老是丟擲這個異常,意思是難看的json資料異常。 Exception in thread "main" com.google.gson.JsonSyntaxException: com.google.gson.stream.Malfo

com.google.gson.stream.MalformedJsonException的解決辦法

關於Gson解析的異常,如果你程式出現以下的異常,有兩種可能性:‘ 1. 找到一個JSON格式的驗證工具,這個網上很多大家可以百度下; 2.你的JSON格式驗證沒有問題,卻一直報這個解析錯誤,請確定你的JSON資料沒有多餘的空格。這個空格有可能在IO流讀取的時候多讀了

Gson解析出現類似錯誤,com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_AR

<span style="font-size:18px;">Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expe

解決hibernate 刪除異常 deleted object would be re-saved by cascade (remove deleted object from associations)

在hibernate 刪除關聯時會出現eleted object would be re-saved by cascade (remove deleted object from associations)的異常,結合別人的和自己的經驗通常有三種解決的方案: 方法1 刪除Se

Gson 解析錯誤Expected BEGIN_ARRAY but was BEGIN_OBJECT

解析錯誤: Expected BEGIN_ARRAY but was BEGIN_OBJECT { “msg”: “繫結成功!”, “code”: “0”, “data”: { “isbind”: “0”

錯誤 com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: closed 解決方案

按照網上配置請求之並未成功拿到資料, 檢視錯誤資訊後發現出現這個異常 com.google.gson.JsonSyntaxException: java.lang.IllegalStateExce

java.lang.NoClassDefFoundError: com/google/gson/Gson錯誤的解決

SSH返回JSON格式的資料時,需要用到gson,將gson-1.6.jar新增進Build path以後執行,出錯: 後來把gson-1.6.jar複製到WEB-INF/lib/下再執行,就沒再出這

Could not find class com.google.gson.Gson

解析json jar ont .class exc 保存 題解 clean ext 在Android開發中使用gson解析json字符串,出現異常:java.lang.classnotfoundexception:com.google.gson.Gson。解決方案如下:

Java企業微信開發_13_異常com.qq.weixin.mp.aes.AesException: 解密後得到的buffer非法

bst 圖片 crypt javax nature current aps protoc spa 一、異常信息 方法:POST@ echostr是否存在 :false java.lang.IllegalArgumentException: 20 > -36