前言
接入某业务接口时,发现其成功和失败状态下,data字段的数据类型并不一致。
接口已上线多时无法随便改动,故需要客户端自己兼容
请求成功时,data是T
类型(某自定义数据类型)
{
"code" : 0,
"data" : {
}
}
请求失败时,data是String
类型
{
"code" : 1000,
"data" : "错误信息"
}
一个data字段对应了两种数据类型,只能把它定义成Object类型。请求成功时,由于data定义成Object类型,默认情况下Gson会将其解析成LinkedTreeMap。使用时需要从map中用key来取值,极其不方便。
另辟蹊径
既然将data定义成Object类型极其不方便,那么data就只能定义成T
类型了。但是这样的话,请求失败时解析又会抛出异常(因为此时data为String类型)。
能否做到请求成功时,将data解析成T
类型,而其它情况不解析data或者将data的值挪到别的字段中(如message字段)?
个人更倾向于后者的想法。也就是能否将请求失败时的JSON修改成以下格式?
{
"code" : 1000,
"data" : null,
"message" : "错误信息"
}
实现方案
基于上述思路,我想到了两种做法
- 自定义OkHttp的Interceptor
- 自定义Gson的TypeAdapter
自定义Interceptor
简单说下做法
- 只拦截某(几)个接口
- 从Response中读取并解析JSON
- 根据
code
判断是否请求成功 - 如果请求失败则生成新的JSON,并返回新的Response
这种做法个人感觉使用比较繁琐,而且需额外解析JSON。具体做法可以看下这篇文章Android 优雅地处理后台返回的骚数据
自定义TypeAdapter
如何使用TypeAdapter修改JSON结构呢?经过一番搜索之后,我在stackoverflow上找到了想要的答案。根据上述回答的实现,我稍微修改了一下
public class CustomizedTypeAdapterFactory<C> implements TypeAdapterFactory {
private final Class<C> mClass;
public CustomizedTypeAdapterFactory(Class