Gson解析服務端返回的多種類型的JSON

遇到幾種Json類型,使用Gson經過自定義解析器解析一下幾種類型的返回數據。web

JSON示例

返回Json中data爲空json

{
    "data": "",
    "code": 1,
    "message": "請求失敗" }

返回Json中data值爲nullide

{
    "data": null,
    "code": 1,
    "message": "請求失敗" }

返回Json中data爲對象類型svg

{
    "data": { "name": "秦川小將", "phone": "182******08" },
    "code": 0,
    "message": "請求成功" }

返回Json中的data爲集合類型ui

{
    "data": [{ "name": "張三", "phone": "182******08" }, { "name": "李四", "phone": "182******08" }],
    "code": 0,
    "message": "請求成功" }

返回Json中的data的值爲字符串,解析時須要去除轉義字符拿到具體的對象this

{ 
 
   
  "data": "{ 
 
   \"id\":2981,\"title\":\"除夕活動啓動頁\",\"content\":\"\",\"url\":\"http://np.test.com/Activity/MonsterNian20180215\"}",
  "code": 0,
  "message": "請求成功"
}

返回Json中的data的值爲字符串,解析時須要去除轉義字符拿到具體的集合對象url

{ 
 
   
  "data": "[{ 
 
   \"id\":2981,\"title\":\"除夕活動啓動頁\",\"content\":\"\",\"url\":\"http://np.test.com/Activity/MonsterNian20180215\"},{ 
 
   \"id\":2849,\"title\":\"默認啓動頁\",\"content\":\"\",\"url\":\"\"}]",
  "code": 0,
  "message": "請求成功"
}

定義基礎類

爲了防止重複寫除data值之外的屬性,這裏定義一個基礎類。spa

public class ResultData<T> {

    public T data;
    public int code;
    public String message;
    /** * 擴展字段 * 0:data爲對象 * 1:data爲集合 * 2:date爲空或者null字段 */
    public int dataType;   

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public int getDataType() {
        return dataType;
    }

    public void setDataType(int dataType) {
        this.dataType = dataType;
    }

    @Override
    public String toString() {
        return "{" +
                "data=" + data +
                ", code=" + code +
                ", message='" + message + '\'' +
                ", dataType=" + dataType +
                '}';
    }
}

自定義解析器

實現 JsonDeserializer 接口重寫 deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) 方法,這裏進行解析處理,針對特殊字段特殊處理。.net

public class JsonFormatParser implements JsonDeserializer<ResultData> {

    private Class mClass;

    public JsonFormatParser(Class tClass) {
        this.mClass = tClass;
    }

    @Override
    public ResultData deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        // 根據Json元素獲取Json對象。
        JsonObject mJsonObject = json.getAsJsonObject();
        ResultData mResult = new ResultData();
        // 因爲Json是以鍵值對的形式存在的,此處根據鍵(data)獲取對應的Json字符串。
        String mJson = mJsonObject.get("data").toString();
        // 判斷是Array仍是Object類型。
        if (mJsonObject.get("data").isJsonArray() && !mJsonObject.get("data").isJsonNull()) {
            mResult.setData(fromJsonArray(mJson, mClass));
            mResult.setDataType(1);
        } else if (mJsonObject.get("data").isJsonObject() && !mJsonObject.get("data").isJsonNull()) {
            mResult.setData(fromJsonObject(mJson, mClass));
            mResult.setDataType(0);
        } else if (mJsonObject.get("data").isJsonPrimitive() && !mJsonObject.get("data").isJsonNull()) {
            // 服務端返回data的值爲"{}","[]",將對象或者集合以字符串的形式返回回來,先去除兩邊的雙引號,再去掉轉義字符。
            String mNewJson = mJson.substring(1, mJson.length() - 1).replaceAll("\\\\", "");
            // 根據處理好的Json字符串判斷是集合仍是對象,再進行解析。
            if (mNewJson.startsWith("[") || mNewJson.endsWith("]")) {
                mResult.setData(fromJsonArray(mNewJson, mClass));
                mResult.setDataType(1);
            } else if (mNewJson.startsWith("{") || mNewJson.endsWith("}")) {
                mResult.setData(fromJsonObject(mNewJson, mClass));
                mResult.setDataType(0);
            } else {
                mResult.setData(fromJsonObject(mResult.toString(), mClass));
                mResult.setDataType(2);
            }
        } else if (mJsonObject.get("data").isJsonNull() || mJsonObject.get("data").getAsString().isEmpty()) {
            mResult.setData(fromJsonObject(mResult.toString(), mClass));
            mResult.setDataType(2);
        }
        // 根據鍵獲取返回的狀態碼。
        mResult.setCode(mJsonObject.get("code").getAsInt());
        // 根據鍵獲取返回的狀態信息。
        mResult.setMessage(mJsonObject.get("message").getAsString());
        return mResult;
    }

    /** * 用來解析對象 */
    private <T> T fromJsonObject(String json, Class<T> type) {
        return new Gson().fromJson(json, type);
    }

    /** * 用來解析集合 */
    private <T> ArrayList<T> fromJsonArray(String json, Class<T> clazz) {
        Type type = new TypeToken<ArrayList<JsonObject>>() {
        }.getType();
        ArrayList<JsonObject> jsonObjects = new Gson().fromJson(json, type);
        ArrayList<T> arrayList = new ArrayList<>();
        for (JsonObject jsonObject : jsonObjects) {
            arrayList.add(new Gson().fromJson(jsonObject, clazz));
        }
        return arrayList;
    }
}

Gson配置

public class FromJsonUtils {

    public static ResultData fromJson(String json, Class clazz) {
        return new GsonBuilder()
                .registerTypeAdapter(ResultData.class, new JsonFormatParser(clazz))
                .enableComplexMapKeySerialization()
                .serializeNulls()
                .create()
                .fromJson(json, ResultData.class);
    }
}

具體調用

public class JsonTest { 
 
   

    private static final String mJson1 = "{ 
 
   \"data\": \"\", \"code\": 1, \"message\": \"請求失敗\"}";
    private static final String mJson2 = "{ 
 
   \"data\": null, \"code\": 1, \"message\": \"請求失敗\"}";
    private static final String mJson3 = "{ 
 
   \"data\": { 
 
   \"name\": \"秦川小將\", \"phone\": \"182******08\"}, \"code\": 0, \"message\": \"請求成功\"}";
    private static final String mJson4 = "{ 
 
   \"data\": [{ 
 
   \"name\": \"張三\", \"phone\": \"182******08\"},{ 
 
   \"name\": \"李四\", \"phone\": \"182******08\"}],\"code\": 0, \"message\": \"請求成功\"}";
    private static final String mJson5 = "{ 
 
   \"data\":\"{ 
 
   \\\"id\\\":2981,\\\"title\\\":\\\"除夕活動啓動頁\\\",\\\"content\\\":\\\"\\\",\\\"url\\\":\\\"http://np.test.com/Activity/MonsterNian20180215\\\"}\",\"code\":0,\"message\":\"請求成功\"}";
    private static final String mJson6 = "{ 
 
   \"data\":\"[{ 
 
   \\\"id\\\":2981,\\\"title\\\":\\\"除夕活動啓動頁\\\",\\\"content\\\":\\\"\\\",\\\"url\\\":\\\"http://np.test.com/Activity/MonsterNian20180215\\\"},{ 
 
   \\\"id\\\":2849,\\\"title\\\":\\\"默認啓動頁\\\",\\\"content\\\":\\\"\\\",\\\"url\\\":\\\"\\\"}]\",\"code\":0,\"message\":\"請求成功\"}";

    public static void main(String[] args) { 
 
   
        ResultData<DataBean> mData1 = FromJsonUtils.fromJson(mJson1, DataBean.class);
        System.out.print("數據類型:" + mData1.getDataType() + "\t解析後取值:" + mData1.getData().getName() + "\n");
        System.out.print("====================================" + "\n");

        ResultData<DataBean> mData2 = FromJsonUtils.fromJson(mJson2, DataBean.class);
        System.out.print("數據類型:" + mData2.getDataType() + "\t解析後取值:" + mData2.getData().getName() + "\n");
        System.out.print("====================================" + "\n");

        ResultData<DataBean> mData3 = FromJsonUtils.fromJson(mJson3, DataBean.class);
        System.out.print("數據類型:" + mData3.getDataType() + "\t解析後取值:" + mData3.getData().getName() + "\n");
        System.out.print("====================================" + "\n");

        ResultData<List<DataBean>> mData4 = FromJsonUtils.fromJson(mJson4, DataBean.class);
        for (DataBean mData : mData4.getData()) { 
 
   
            System.out.print("數據類型:" + mData4.getDataType() + "\t解析後取值:" + mData.getName() + "\n");
        }
        System.out.print("====================================" + "\n");

        ResultData<ActivityBean> mData5 = FromJsonUtils.fromJson(mJson5, ActivityBean.class);
        System.out.print("數據類型:" + mData5.getDataType() + "\t解析後取值:" + mData5.getData().getTitle() + "\n");
        System.out.print("====================================" + "\n");

        ResultData<List<ActivityBean>> mData6 = FromJsonUtils.fromJson(mJson6, ActivityBean.class);
        for (ActivityBean mActivity : mData6.getData()) { 
 
   
            System.out.print("數據類型:" + mData6.getDataType() + "\t解析後取值:" + mActivity.getTitle() + "\n");
        }
    }
}

打印輸出: code

數據類型:2 解析後取值:null ====================================
數據類型:2 解析後取值:null ====================================
數據類型:0 解析後取值:秦川小將 ====================================
數據類型:1  解析後取值:張三
數據類型:1 解析後取值:李四 ====================================
數據類型:0 解析後取值:除夕活動啓動頁 ====================================
數據類型:1  解析後取值:除夕活動啓動頁
數據類型:1  解析後取值:默認啓動頁

示例數據實體類

public class DataBean {

    public String name;

    public String phone;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

}
public class ActivityBean {

    private int id;
    private String title;
    private String content;
    private String url;

    public int getId() {
        return id;
    }

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

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

本文分享 CSDN - 秦川小將。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索