Gson使用指南(四)

本文为作者根据日常使用结合Gson源码注释及wiki所作的原创内容,转载请注明出处。

如果遇到问题请点击底部查看原文

该系列其它文章

你真的会用Gson吗?Gson使用指南(一)

你真的会用Gson吗?Gson使用指南(二)

你真的会用Gson吗?Gson使用指南(三)

你真的会用Gson吗?Gson使用指南(四)

注:此系列基于Gson 2.4。

本次文章的主要内容:

TypeAdapter

JsonSerializer与JsonDeserializer

TypeAdapterFactory

@JsonAdapter注解

TypeAdapter与 JsonSerializer、JsonDeserializer对比

TypeAdapter实例

结语

后期预告

一、TypeAdapter

是Gson自2.0(源码注释上说的是2.1)开始版本提供的一个抽象类,用于接管某种类型的序列化和反序列化过程,包含两个注要方法 和 其它的方法都是方法并最终调用这两个抽象方法。

注意:TypeAdapter 以及 JsonSerializer 和 JsonDeserializer 都需要与 示或配合使用,下面将不再重复说明。

使用示例:

UserTypeAdapter的定义:

当我们为 注册了 之后,只要是操作 那些之前介绍的 、、、、通通都黯然失色,失去了效果,只会调用我们实现的 方法,我想怎么写就怎么写。

再说一个场景,在该系列的第一篇文章就说到了Gson有一定的容错机制,比如将字符串 转成int 的,但如果有些情况下给你返了个空字符串怎么办(有人给我评论问到这个问题)?虽然这是服务器端的问题,但这里我们只是做一个示范。

int型会出错是吧,根据我们上面介绍的,我注册一个TypeAdapter 把 序列化和反序列化的过程接管不就行了?

注:测试空串的时候一定是而不是,代表的是没有json串,才代表json里的。

你说这一接管就要管两样好麻烦呀,我明明只想管序列化(或反列化)的过程的,另一个过程我并不关心,难道没有其它更简单的方法么? 当然有!就是接下来要介绍的JsonSerializer与JsonDeserializer

二、JsonSerializer与JsonDeserializer

和 不用像一样,必须要实现序列化和反序列化的过程,你可以据需要选择,如只接管序列化的过程就用 ,只接管反序列化的过程就用 ,如上面的需求可以用下面的代码。

下面是所有数字都转成序列化为字符串的例子

注:必须使用包装类型,所以,,和是行不通的。同时不能使用父类来替上面的子类型,这也是为什么要分别注册而不直接使用的原因。

上面特别说明了不行,那就是有其它方法可行咯?当然!换成** **就可以使用而不用一个一个的当独注册啦!

registerTypeAdapter与registerTypeHierarchyAdapter的区别:

注:如果一个被序列化的对象本身就带有泛型,且注册了相应的,那么必须调用,明确告诉Gson对象的类型。

三、TypeAdapterFactory

TypeAdapterFactory,见名知意,用于创建TypeAdapter的工厂类,通过对比,确定有没有对应的,没有就返回null,与配合使用。

四、@JsonAdapter注解

相较之前介绍的 、、、、这几个注解都是比较特殊的,其它的几个都是用在POJO的字段上,而这一个是用在POJO类上的,接收一个参数,且必须是,或这三个其中之一。

上面说和都要配合使用,但每次使用都要注册也太麻烦了,就是为了解决这个痛点的。

使用方法(以User为例):

使用时不用再使用 去注册了。

注:仅支持 或( 2.7开始已经支持 JsonSerializer/JsonDeserializer)

注意:的优先级比的优先级更高。

五、TypeAdapter与 JsonSerializer、JsonDeserializer对比

六、TypeAdapter实例

注:这里的TypeAdapter泛指、和。

这里的TypeAdapter 上面讲了一个自动将 字符串形式的数值转换成int型时可能出现 空字符串的问题,下面介绍一个其它读者的需求:

服务器返回的数据中data字段类型不固定,比如请求成功data是一个List,不成功的时候是String类型,这样前端在使用泛型解析的时候,怎么去处理呢?

其实这个问题的原因主要由服务器端造成的,接口设计时没有没有保证数据的一致性,正确的数据返回姿势:同一个接口任何情况下不得改变返回类型,要么就不要返,要么就返空值,如、,

但这里还是给出解决方案:

方案一:

方案二:

要注意的点:

必须使用方法,不然对List的子类无效,但如果POJO中都是使用List,那么可以使用。

对于是数组的情况,需要创建一个新的Gson,不可以直接使用context,不然gson又会调我们自定义的造成递归调用,方案二没有重新创建Gson,那么就需要提取出List

中E的类型,然后分别反序列化适合为E手动注册了TypeAdaper的情况。

从效率上推荐方案二,免去重新实例化Gson和注册其它TypeAdapter的过程。

结语

Gson系列总算是完成了,感觉写得越来越差了,我怕我写得太啰嗦,也不能总是大片大片的贴代码,所以可能有的地方写得并不详细,排版也不美观,但都些都不重点,重点是Gson里我们能用上的都一一介绍一遍,只要你确确实实把我这几篇文章上的内容都学会的话,以后Gson上的任何问题都不再是问题,当然可能很多内容对于实际的开发中用的并不多,但下次有什么疑难杂症就难不倒你了。

本系列不提供Demo源码,最重要的是自己实验。

写一篇文章还是要花不少时间和精力,要写示例、调式、组织语言、码字等等,加上关注的人在慢慢的增加的同时既给了我动力也给我不少压力,如有纰漏或者更好的例子都可以和我交流。

后期预告:

之前有人给我评论说 出一点 retrofit 相关内容,我想了想,出是会出,但在此之前我想先出大概3~4篇文章用于介绍泛型、反射、注解和HTTP的相关内容,当你确实掌握之后,我打包票你只需要看一遍Retrofit官方教程的代码示例,都不用看其它英文说明,就可以轻松玩转Retrofit。不服来战!

  • 发表于:
  • 原文链接:https://kuaibao.qq.com/s/20180701G0ZDQI00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券