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;
    }
}
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蒙同學

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值