Gson 技巧

Posted by hurshi on 2019.04.28

注解

  • @SerializedName: 配置 JSON 字段名字
  • @Expose:配置是否参与序列化和反序列化
    1. 有2个配置项,默认都为 True : @Expose(serialize = true,deserialize = false)
    2. new Gson()不起作用,需要配合 GsonBuilder.excludeFieldsWithoutExposeAnnotation()使用,并且需要对每个字段都显式暴露出来,不然该字段就不会参与序列化/反序列化

GsonBuilder

  • 配置:
    1. .serializeNulls() :序列化为 null 的字段。
    2. .setDateFormat():设置日期格式,例如:setDateFormat("yyyy-MM-dd")
    3. .disableInnerClassSerialization():禁止序列化内部类。
    4. .generateNonExcutableJson():生成不可直接解析的 JSON,会多 )]}' 这 4 个字符。
    5. .disableHtmlEscaping():禁止转移 HTML 标签
    6. .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