注解
@SerializedName:
配置 JSON 字段名字@Expose:
配置是否参与序列化和反序列化- 有2个配置项,默认都为 True :
@Expose(serialize = true,deserialize = false)
new Gson()
不起作用,需要配合GsonBuilder.excludeFieldsWithoutExposeAnnotation()
使用,并且需要对每个字段都显式暴露出来,不然该字段就不会参与序列化/反序列化
- 有2个配置项,默认都为 True :
GsonBuilder
- 配置:
.serializeNulls()
:序列化为 null 的字段。.setDateFormat()
:设置日期格式,例如:setDateFormat("yyyy-MM-dd")
。.disableInnerClassSerialization()
:禁止序列化内部类。.generateNonExcutableJson()
:生成不可直接解析的 JSON,会多)]}'
这 4 个字符。.disableHtmlEscaping()
:禁止转移 HTML 标签.setPrettyPrinting()
:格式化输出
TypeAdapter
-
举个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13
class IntegerDefault0Adapter : JsonDeserializer<Int> { override fun deserialize(json: JsonElement?, typeOfT: Type?, context: JsonDeserializationContext?): Int { try { return json!!.getAsInt() } catch (e: NumberFormatException) { return 0 } } } val newUser = GsonBuilder() .registerTypeAdapter(Int::class.java, IntegerDefault0Adapter()) .create().fromJson(jsonStr,User::class.java)
例子中的表示:我接管了所有的 Int 型的序列化/反序列化。对 Int 型数据,如果解析出错,则使用默认值0。
-
registerTypeHierarchyAdapter() 的区别
看看源码,细心的朋友应该发现了,注册 TypeAdapter 的时候,还有
registerTypeHierarchyAdapter()
方法,它和registerTypeAdapter()
方法有什么区别呢?区别就在于,接管的类型类,是否支持继承。例如前面例子中,我们只接管了 Int 类型,而数字类型还有其他的例如 Long、Float、Double 等并不会命中到。那假如我们注册的是这些数字类型的父类 Number 呢?使用
registerTypeAdapter()
也不会被命中,因为类型不匹配。此时就可以使用
registerTypeHierarchyAdapter()
方法来注册,它是支持继承的。 -
TypeAdapterFactory 工厂类的使用
使用
registerXxx()
方法可以链式调用,注册各种 Adapter。如果嫌麻烦,还可以使用 TypeAdapterFacetory 这个 Adapter 工厂,配合
registerTypeAdapterFactory()
方法,根据类型来返回不同的 Adapter。其实只是换个了实现方式,并没有什么太大的区别。
-
@JsonAdapter 注解
@JsonAdapter 和前面介绍的 @SerializedName、@Expose 不同,不是作用在字段上,而是作用在 Java 类上的。
它指定一个“Adapter” 类,可以是 TypeAdapter、JsonSerializer 和 JsonDeserializer 这三个中的一个。
@JsonAdapter 注解只是一个更灵活的配置方式而已,了解一下即可。
出处
作者:HanDrush
标题:接口返回的 JSON,再离谱也有办法,谈谈 JSON 容错!
链接:https://juejin.im/post/5cb72f755188253249739246