也许你和我一样有这样的经历,后台的json字段格式总是各种变化,一个字段,既可能是一个普通的String,也可能是Object,一会是int Array,一会是Object Array,甚至是Map。原因不外乎,历史遗漏代码啊,进度紧张没时间磨平差异啊,或者干脆就是无法控制的因素等。今天我就简单总结下,该如何用Gson库的TypeArray特性,优雅的处理这种糟糕格式的json。
年前和团队一起赶项目进度,加上搬家什么的各种杂事,好久没静下心写篇文章了,转眼2017年,趁着年前进度收尾,不是特别忙碌的功夫,我争取吧这段时间中遇到的技术问题,总结下来,基本都以实战为主,短篇。
事件篇–可怕的Json格式
首先我们来看这样一串json:
1 |
|
1 |
|
很简单对不对,但是还有其它几种可能情况:
也许30号球衣那位,在后台看来就是库里,所以这会变成Person字段变成数值了
1 |
|
你看,后台贴心的放上了库里的生日,Person字段也自然而然变成了对象
1 | { |
库里,你不是一个人
1 | { |
也许人多了,忘却你生日,只记住你的姓名
1 | { |
后台也许有时候觉得你需要一个key,方便在人群中找到你。
1 | { |
疑难篇–Gson
我们知道,Gson默认的json转Object的是这样做的:
1 | Gson gson = new Gson(); |
Gson可以通过注册GsonBuilder()的registerTypeAdapter的方法,手动注入某一个类的解析规则,
再看Gson中几种Json格式所对应的类的关系,看图一目了然:
我们只要针对每一层JsonElement判断具体的类型并手动创建对象和赋值,就可以了。
解决篇–自定义具体类的解析方式
不过俗话说得好,不会投三分的Android开发不是好的产品,我们怎么能被这样恶心的接口轻易地恶心倒呢,来看Gson库给我们提供的泛型支持工具 TypeToken
首先定义一个合适的类结构,表示Person,这里仅作参考
1 | public class Persons { |
1 | public class Person { |
1 | public class Data { |
接着,定义对应的TypeToken和JsonDeserializer,针对该类手动处理Json解析
1 | public static final Type TypePersons = new TypeToken<Persons>() { |
1 | public static JsonDeserializer<Persons> personsJsonDeserializer = new JsonDeserializer<Persons>() { |
1 | Gson gson = new GsonBuilder() |
代码应该写得很清楚了,以上。