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

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

JSON示例

返回Json中data爲空

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

返回Json中data值爲null

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

返回Json中data爲對象類型

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

返回Json中的data爲集合類型

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

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

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

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

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

定義基礎類

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

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) 方法,這裏進行解析處理,針對特殊字段特殊處理。

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");
        }
    }
}

打印輸出:

數據類型: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;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章