Gson解析数组多类型元素
本文的出现是为了解决以下需求:使用Gson对json数组进行解析,但是数组里面元素的类型是多种的。数据如下:
{"list":[{
"type":0,
"data":{
"id":1,
"color":"red"
}
},{
"type":1,
"data":{
"id":1,
"name":"case"
}
}]}
可能你会说data中的对应的实体可以包括所有data中的字段就可以了,那么你采用这种方法我只能说太low了,不是不可以这么做,要是遇到很庞大的实体类,那么你会发现里面甚至需要上百个字段。我们这里举例只是为了说明方便,所以给的数据都比较简单,重在思路。
如何设计
为了解决上面的问题,那么我想到的是三种处理方法:
方法一:也就是上文所说的那种很low的做法咯,把所有的字段都放在一个实体类中。
这种方法对应初级选手确实感觉还不错,不用思考太多就可以解决解析问题,不过这不是我们程序员应该满足的。(上文已经吐槽过了)
方法二:对于数组中data数据结构不同,那么字段就不统一命名成data,而是根据实的结构服务器返回不同的字段,如:colorEntity,userEntity。那么对应的实体类应该是这样的形式:
public class ListEntity{
int type;
User userEntity;
Color colorEntity;
}
缺点很明显。①没有统一的数据字段;②添加新类型,服务器加字段需要检查新加字段名不能和已有的字段名重复(如何已有的类型多,那么服务器工作就需要更细心);③Gson对应的解析实体类会因为list结构丰富而变得很庞大,因为每种类型都需要一个对应的字段。
当然优点也很明显。简单易懂,遇到问题很容易处理,可读性强。
此方法前提条件就是需要服务器配合,要是你用现成的服务器那么这种方法完全就不用考虑了。
方法三:根据不同的type返回不同的data值(也就是现在示例中的样子),添加Gson解析器来完成解析(可能很多童鞋对此感到很陌生,其实很简单)。
这种方法就需要对Gson的解析有一定了解。本文也是重点解说如何设计这种解析并且给出demo,下文就是对此方法进行讲解。
1、Gson对应的实体类
首先我们知道ArrayList里面的元素都是相同的类型,那么如何才能使用不同的类型呢?当然就是集合里面的元素使用一个基类,然后具体的实体类都继承这个基类。示例:
我们有3个类:
这个类就是刚刚说的基类,所有list字段里面对应实体的基类
public class TypeSuper {
}
list字段里面对应的其中一种类型TypeA
public class TypeA extends TypeSuper {
public int id;
public String name;
public TypeA(int id, String name) {
super();
this.id = id;
this.name = name;
}
}
list字段里面对应的其中另一种类型TypeB
public class TypeB extends TypeSuper {
public int id;
public String color;
public TypeB(int id, String color) {
super();
this.id = id;
this.color = color;
}
}
Gson对应的实体类TypeResult
public class TypeResult {
List<TypeSuper> data = new ArrayList<TypeSuper>();
}
2、Gson反序列化
根据json字符串进行解析,示例代码如下:
Gson解析器TypeResultDeserializer
public class TypeResultDeserializer implements JsonDeserializer<TypeResult> {
@Override
public TypeResult deserialize(JsonElement arg0, Type arg1,
JsonDeserializationContext arg2) throws JsonParseException {
JsonObject obj = arg0.getAsJsonObject();
JsonArray asJsonArray = obj.get("list").getAsJsonArray();
TypeResult result = new TypeResult();
for (JsonElement jsonElement : asJsonArray) {
JsonObject jsonOb = jsonElement.getAsJsonObject();
int type = jsonOb.get("type").getAsInt();
if (type == 0) {
JsonObject child = jsonOb.get("data").getAsJsonObject();
int id = child.get("id").getAsInt();
String name = child.get("color").getAsString();
result.data.add(new TypeB(id, name));
} else if(type == 1) {
JsonObject child = jsonOb.get("data").getAsJsonObject();
int id = child.get("id").getAsInt();
String name = child.get("color").getAsString();
result.data.add(new TypeA(id, name));
}
}
return result;
}
}
3、使用解析器解析Demo
public class Test {
public static void main(String[] args) {
GsonBuilder gsonb = new GsonBuilder();
gsonb.registerTypeAdapter(TypeResult.class, new TypeResultDeserializer());
gsonb.serializeNulls();
Gson gson = gsonb.create();
String json = "{\"list\":[{" + "\"type\":0," + "\"data\":{"
+ "\"id\":1," + "\"color\":\"red\"" + "}" + "},{"
+ "\"type\":1," + "\"data\":{" + "\"id\":1,"
+ "\"color\":\"case\"" + "}" + "}]}";
List<TypeSuper> item = gson.fromJson(json, TypeResult.class).data;
for (TypeSuper baseItem : item) {
if (baseItem instanceof TypeA) {
System.out.println(((TypeA) baseItem).name);
} else if (baseItem instanceof TypeB) {
System.out.println(((TypeB) baseItem).color);
}
}
}
}
看完整个步骤,最核心的就是自定义解析器,根据自己的需求进行解析。以上就完整解说了方式三的具体操作流程。如果读者有更好的方式解析希望可以分享一下。
如果文中有任何疑问或者不妥之处欢迎留言交流。在此也留下QQ群311536202,欢迎交流。
Gson解析数组多类型元素的更多相关文章
- Gson解析数组和list容器
Gson解析数组和list容器 使用Gson解析首先须要增加架包文件:gson-2.2.4.jar 定义一个类Student: public class Student { String name=& ...
- 用Gson解析没有数据头的纯数组json字符串
无数据头Json字符串 Json字符串只有数组,而次数组没有名字,如下 [ { "name": "zhangsan", "age": &qu ...
- 【转】采用Gson解析含有多种JsonObject的复杂json
本文对应的项目是MultiTypeJsonParser ,项目地址 https://github.com/sososeen09/MultiTypeJsonParser 0 前奏 使用 Gson 去解析 ...
- 大话JSON之Gson解析JSON
(三)解析Json数组(多条Json数据) 比如有如下Json数据: [{'name':'John', 'grade':[{'course':'English','score':100},{'cour ...
- Android中使用Gson解析JSON数据的两种方法
Json是一种类似于XML的通用数据交换格式,具有比XML更高的传输效率;本文将介绍两种方法解析JSON数据,需要的朋友可以参考下 Json是一种类似于XML的通用数据交换格式,具有比XML更高的 ...
- Gson解析的小例子
最近解析些复杂的节点数据解析,用安卓自带的json解析比较麻烦所以只能用Gson解析,所以从网上下了点demo来看看 http://blog.csdn.net/tkwxty/article/detai ...
- Android网络之数据解析----使用Google Gson解析Json数据
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- Gson解析json数据(转)
一. www.json.org这是JSON的官方网站. 首先,我,我们需要在code.google.com/p/google-gson/downloads/list下载JSON的jar包,解析后把gs ...
- Android--------使用gson解析json文件
##使用gson解析json文件 **json的格式有两种:** **1. {}类型,及数据用{}包含:** **2. []类型,即数据用[]包含:** 下面用个例子,简单的介绍gson如何解析jso ...
随机推荐
- PHP 开发社区微信服务号实战图解
本博文就月初刚上线的微信服务号,图文进行总结分享给大家. 去年年底,我所在的团队讨论要开发微信号,话题由此拉开: 原来有一个3年前注册的微信号,但是后台操作无法从“订阅号”变更为“服务号”,随即找腾讯 ...
- jQuery演示10种不同的切换图片列表动画效果以及tab动画演示 2
很常用的一款特效纯CSS完成tab实现5种不同切换对应内容效果 实例预览 下载地址 实例代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ...
- 【原】在windows下使用VirtualEnv
VirtualEnv可以方便的解决不同项目中对类库的依赖问题.这通常是通过以下方式实现的:首先将常用的类库安装在系统环境中:然后为每个项目安装独立的类库环境.这样子可以保证每个项目都运行在独立的类库环 ...
- 如何启动/停止/重启MySQL
启动.停止.重启 MySQL 是每个拥有独立主机的站长必须要撑握的操作,下面为大家简单介绍一下操作方法: 一.启动方式 1.使用 service 启动:service mysqld start 2.使 ...
- atitit.提升稳定性---hibernate 增加重试retry 机制解决数据库连接关闭
atitit.提升稳定性---hibernate 增加重试retry 机制解决数据库连接关闭 1. 流程总结 retry(5times).invoke(xxx).test().rest().$() t ...
- 更新日志 - BugHD 与你的应用一起成长
上周 BugHD Android客户端上线了,下载地址在此,欢迎大家体验并提出反馈.本周增加 BugHD 和 fir.im 的新功能,同时也做出一些体验优化. BugHD 新增功能 1.新增安装量.启 ...
- iOS开发-NSURLSession详解
Core Foundation中NSURLConnection在2003年伴随着Safari浏览器的发行,诞生的时间比较久远,iOS升级比较快,AFNetWorking在3.0版本删除了所有基于NSU ...
- 淘宝开放平台TOP测试环境
沙箱测试环境 淘宝沙箱环境是淘宝开放平台(TOP)提供给独立软件开发商(ISV)的测试环境.数据完全独立,大部分API已经部署到该环境中供ISV进行API的功能测试,对与APP的调用量无限制,但获取大 ...
- ASP.NET Web API模型验证以及异常处理方式
ASP.NET Web API的模型验证与ASP.NET MVC一样,都使用System.ComponentModel.DataAnnotations. 具体来说,比如有:[Required(Erro ...
- Backbone.js Wine Cellar 教程
中文版: http://rd.189works.com/article-74541-1.html http://www.189works.com/article-74542-1.html http:/ ...