为了避免篇幅过长,所以将文章拆分成了两篇
通过上一篇的学习,我们已经能够满足大部分需求了,但是需求是不断变化的,接下来让我们学习使用Gson如何处理更恶心的数据。
不知道你们有没有碰到过类似这样的数据,反正我肯定碰到过 :)
{
"code":200,
"msg":"success",
"data":[
{
"id":1,
"name":"Guangzhou"
},
null
]
}
甚至是这样的
{
"code":200,
"msg":"success",
"data":[
{
"id":1,
"name":"Guangzhou"
},
null,
]
}
![](https://img.haomeiwen.com/i16235667/21aedd44d009e69e.jpg)
如果我们直接使用Gson进行解析
String jsonStr = "{\"code\":200,\"msg\":\"success\",\"data\":[{\"id\":1,\"name\":\"Guangzhou\"},null,]}";
Result<List<City>> result = gson.fromJson(jsonStr, new TypeToken<Result<List<City>>>() {}.getType());
Log.e("反序列化结果", result.toString());
//反序列化结果,会得到一个size为3的List<City>
Result{code=200, msg='success', data=[City{id=1, name='Guangzhou'}, null, null]}
然后当你使用for循环遍历时,就会瞬间boom,抛出一个java.lang.NullPointerException
for (int i = 0; i < result.getData().size(); i++) {
Log.e("City", result.getData().get(i).toString());
}
根据上一篇的CollectionTypeAdapterFactory
,机智的你已经发现了有一段处理Collection内instance的代码
![](https://img.haomeiwen.com/i16235667/261b760b71bc88a2.png)
我们可以在此处打一个断点进行debug跟踪,发现正是从这里进行了Collection内部的解析
![](https://img.haomeiwen.com/i16235667/663b797873cbc697.png)
所以我们就可以在这里做文章,改为
public Collection<E> read(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
in.nextNull();
//源码中是 return null,改为 return empty constructor
return constructor.construct();
}
Collection<E> collection = constructor.construct();
in.beginArray();
while (in.hasNext()) {
//如果{}为null,则跳过
if (in.peek() == JsonToken.NULL) {
in.skipValue();
continue;
}
E instance = elementTypeAdapter.read(in);
collection.add(instance);
}
in.endArray();
return collection;
}
再次进行解析后
反序列化结果:
Result{code=200, msg='success', data=[City{id=1, name='Guangzhou'}]}
大功告成!您已经成为Gson异常数据处理的大佬级人物了!
![](https://img.haomeiwen.com/i16235667/14fd43d7a26023c5.jpg)
这里还有一种异常数据的解析我暂时还没有想到很好的办法去处理,后面解决了会补充进来,如果已经解决的大佬希望能够分享、交流一下,万分感谢!
{
"code":200,
"msg":"success",
"data":[
{
"id":1,
"name":"Guangzhou"
},
{
}
]
}
如果你们在工作中也遇到了这样的问题,这里有几本我假装混迹互联网圈多年总结出来的秘籍表情包,拿去参考吧。
![]() |
![]() |
![]() |
---|
记录,分享,交流。
网友评论