引言
在开发过程中,我们现在绝大部分都是使用JSON
格式进行数据交互,但是各个接口返回的数据内容不同,如果每个接口都进行GSON
解析代码会显得比较臃肿。
背景
我们先来看一下JSON
的几种基本格式:
# 第一种
{"status":0,"message":"成功","data":{"age":"15","sex":"女"}}
# 第二种
{"status":0,"message":"成功","data":{"name":"陌上花开","user":{"age":"15","sex":"女"},"list":[{"age":"15","sex":"女"},{"age":"15","sex":"男"}]}}
# 第三种
{"status":0,"message":"成功","data":[{"age":"15","sex":"女"},{"age":"15","sex":"男"}]}
经过分析,发现以上三种JSON
字符串有一个共同的特点,JSON
的结构一致:
{"status":0,"message":"成功","data": ...}
其中:
status
:返回状态message
:返回消息data
:返回数据
返回数据相同的JSON
格式结构,因此如果定义一种通用的模型对应到此结构进行解析将会大大提高开发效率和代码简洁。但是值得注意的是data
中的数据类型不一致,如:第一种包含的是简单对象,第二种包含的是对象中嵌套数组或对象,第三种包含的是List
集合。所以针对data
数据类型不一致的情况,我们可以使用泛型来解决。
效果图:
解析
对于第一种和第二种JSON
格式的解析我们可以采用以下方式来进行:
public class Common<T> {
private int status;
private String message;
private T data;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
@Override
public String toString() {
return "Common{" +
"status=" + status +
", message='" + message + '\'' +
", data=" + data +
'}';
}
public static Common fromJson(String json, Class clazz) {
Gson gson = new Gson();
Type objectType = type(Common.class, clazz);
return gson.fromJson(json, objectType);
}
public String toJson(Class<T> clazz) {
Gson gson = new Gson();
Type objectType = type(Common.class, clazz);
return gson.toJson(this, objectType);
}
static ParameterizedType type(final Class raw, final Type... args) {
return new ParameterizedType() {
public Type getRawType() {
return raw;
}
public Type[] getActualTypeArguments() {
return args;
}
public Type getOwnerType() {
return null;
}
};
}
}
对于第三种JSON
格式,由于data
是List
类型的,如果使用以上方式进行解析将无法得到List<T>
类型的class
,所以针对第三种格式可以采用以下方式来进行:
public class CommonList<T> {
private int status;
private String message;
private List<T> data;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<T> getData() {
return data;
}
public void setData(List<T> data) {
this.data = data;
}
@Override
public String toString() {
return "CommonList{" +
"status=" + status +
", message='" + message + '\'' +
", data=" + data +
'}';
}
public static CommonList fromJson(String json, Class clazz) {
Gson gson = new Gson();
Type objectType = type(CommonList.class, clazz);
return gson.fromJson(json, objectType);
}
public String toJson(Class<T> clazz) {
Gson gson = new Gson();
Type objectType = type(CommonList.class, clazz);
return gson.toJson(this, objectType);
}
static ParameterizedType type(final Class raw, final Type... args) {
return new ParameterizedType() {
public Type getRawType() {
return raw;
}
public Type[] getActualTypeArguments() {
return args;
}
public Type getOwnerType() {
return null;
}
};
}
}
使用
为了契合我们实际开发需求(实际开发过程中,我们往往会在封装好的方法中进行网络请求的数据解析),因此这里我们简单模拟实际情景进行接口封装,当然也会贴出直接使用的方式。
1.定义数据回调接口
public abstract class Callback<T> {
public abstract void onSuccess(T t);
public abstract T parseNetworkResponse(String str);
}
2.定义对象解析接口
public abstract class DataCallback<T> extends Callback<Common<T>> {
@Override
public Common<T> parseNetworkResponse(String str) {
Class<T> entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
return Common.fromJson(str, entityClass);
}
}
3.定义集合解析接口
public abstract class ListCallback<T> extends Callback<CommonList<T>> {
@Override
public CommonList<T> parseNetworkResponse(String str) {
Class<T> entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
return CommonList.fromJson(str, entityClass);
}
}
4.三种JSON
格式的接口调用
# 第一种
DataUtil.getData(Constant.json1, new DataCallback<UserBean>() {
@Override
public void onSuccess(Common<UserBean> userCommon) {
}
});
# 第二种
DataUtil.getData(Constant.json2, new DataCallback<PersonBean>() {
@Override
public void onSuccess(Common<PersonBean> userCommon) {
}
});
# 第三种
DataUtil.getData(Constant.json3, new ListCallback<UserBean>() {
@Override
public void onSuccess(CommonList<UserBean> userCommonList) {
}
});
5.三种JSON
格式的直接调用
# 第一种
Common<UserBean> user = Common.fromJson(Constant.json1, UserBean.class);
# 第二种
Common<PersonBean> person = Common.fromJson(Constant.json2, PersonBean.class);
# 第三种
CommonList<UserBean> users = CommonList.fromJson(Constant.json3, UserBean.class);
项目地址 ☞ 传送门