Gson 解析服务端返回的多种类型的 JSON
Posted code小生
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Gson 解析服务端返回的多种类型的 JSON相关的知识,希望对你有一定的参考价值。
关注 code小生 ,每日一篇技术推送!
遇到几种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;
}
}
以上是关于Gson 解析服务端返回的多种类型的 JSON的主要内容,如果未能解决你的问题,请参考以下文章