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源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索