使用GSON和泛型解析约定格式的JSON字符串
2017-04-24 10:20
615 查看
引言
在开发过程中,我们现在绝大部分都是使用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);
项目地址 ☞ 传送门
相关文章推荐
- 使用GSON和泛型解析约定格式的JSON串
- 使用GSON和泛型解析约定格式的JSON串
- 使用库org.json 和 Gson 解析 JSON格式字符串
- 使用GSON和泛型解析约定格式的JSON串(转)
- 使用Gson解析json格式的字符串的正确方式
- 使用Gson解析json格式的字符串的正确方式
- 使用GSON和泛型解析约定格式的JSON串(转)
- Android JSON数据格式的解析,与简单对象、带泛型的List和Map的转换,以及GSON的使用
- 使用GSON和泛型解析约定格式的JSON串
- gson 的使用 解析json字符串
- 解决android使用gson解析json字符串,并使用混淆编译方式打包apk遇到的问题
- 解决android使用gson解析json字符串,并使用混淆编译方式打包apk遇到的问题
- JSON数据的格式和解析(使用GSON)入门
- 使用Gson对象将json格式的字符串与集合和对象互转
- 使用Gson解析常见json字符串
- 解决android使用gson解析json字符串,并使用混淆编译方式打包apk遇到的问题
- Retrofit中使用GSON解析定制格式的JSON
- Gson利用泛型将Http请求返回的Json字符串快速解析模板
- 百度天气api开发 全解析xml和json格式 使用json-lib jsonObject、 Gson 方式把json 转换成 java对象
- 使用eval()解析JSON格式字符串应注意的问题