GsonBuilder 初探
Gson 类提供的API满足我们大部分的使用场景,但是有时我们需要更强大的功能,这时候就需要使用 GsonBuilder。
GsonBuilder,见名知意,它用于构建Gson的实例,用来改变Gson的默认配置。
GsonBuilder 用法
|
|
我们来看一个示例:
|
|
从结果可以看出email字段,在输出的json串中没有体现。如果我们需要通过日志输出查看User中所有的字段。
再来看一些高级点的功能,格式化输出,日期时间等
字段过滤
在项目开发过程中,我们有些字段是不需要进行序列化的,那么在序列化时,我们就要将这些字段过滤,让我们来看一下 Gson 如何解决的这个问题,它提供四种方式:
基于 @Expose 注解
|
|
看源码注释,我们得知: @Expose 有两个属性 serialize 和 deserialize
,默认值为 true。
|属性|true|false|
|–|–|
|serialize|序列化|不序列化|
|deserialize|反序列化|不反序列化|
|
|
@Expose 注解必须配合 GsonBuilder 使用。
基于版本 setVersion()
Gson 另外提供了两个注解 @Since 和 @Util ,配合setVersion(double version) 使用。当然我们还是通过代码来演示:
- 创建Gson实例 调用 setVersion(),设置版本为1.0123Gson gson = new GsonBuilder().setVersion(1.0).create();
|
|
@Since
当前版本大于或等于@Since标注版本时,字段可以序列化和反序列化。
上面代码 emailAddress 可以序列化和反序列化,address 不可以。@Util
当前版本小于@Util标注版本时,字段可以序列化和反序列化。
上面代码 username 可以序列化和反序列化,password 不可以。
注:当一个字段被 @Since 和 @Util 同时注解时,需两者同时满足条件。
基于访问修饰符
常用的修饰符 public、static、final、private、protected等等。
我们可以通过 excludeFieldsWithModifiers(int… modifiers)来过滤字段。
使用GsonBuilder.excludeFieldsWithModifiers构建gson,支持int形的可变参数,值由java.lang.reflect.Modifier提供,下面的程序排除了privateField 、 finalField 和staticField 三个字段。
自定义规则
自定义规则相对麻烦一些,但是更强大,更灵活。
Gson提供了ExclusionStrategy接口,同样需要使用GsonBuilder,相关API 分别是addSerializationExclusionStrategy(序列化)和addDeserializationExclusionStrategy(反序列化)。下面我们以序列化为例:
序列化命名自定义
涉及到的API :
- GsonBuilder : setFieldNamingPolicy() 和 setFieldNamingStrategy()
- FieldNamingStrategy 接口
- 实现了FieldNamingStrategy 的枚举类 FieldNamingPolicy
Gson 提供的默认实现
setFieldNamingPolicy() 结合 FieldNamingPolicy
FieldNamingPolicy | 输出结果(emailAddress字段为例) |
---|---|
IDENTITY | {“emailAddress”:”leo@example.com”} |
LOWER_CASE_WITH_DASHES | {“email-address”:”leo@example.com”} |
LOWER_CASE_WITH_UNDERSCORES | {“email_address”:”leo@example.com”} |
UPPER_CAMEL_CASE | {“EmailAddress”:”leo@example.com”} |
UPPER_CAMEL_CASE_WITH_SPACES | {“Email Address”:”leo@example.com”} |
自定义规则
setFieldNamingStrategy() 结合 FieldNamingStrategy
注: @SerializedName 注解拥有最高优先级,在 @SerializedName 标注的字段上 FieldNamingStrategy 不生效!
随心所欲玩转序列化和反序列化
TypeAdapter
TypeAdapter
是Gson2.1提供的一个抽象类,用于POJO的序列化和反序列化。主要重写两个方法 write(JsonWriter out, T value) 和 read(JsonReader in)
使用示例:
|
|
当我们为 User.class 注册了 TypeAdapter 之后,操作User.class的 那些@SerializedName、FieldNamingStrategy、@Since、@Until、@Expose,q全部废废,只会调用我们实现的UserTypeAdapter.write(JsonWriter, User) 方法,我们想怎么玩就怎么玩。
当然上面的序列化和反序列化的操作是有缺点的,如果我们想要对多个POJO随心所欲的操作,那么在创建 Gson 实例就要注册很多个 TypeAdapter ,追求代码洁癖的人会疯的。解决这个问题就需要用到 @JsonAdapter 注解。
@JsonAdapter
前面提到 @JsonAdapter 可以解决注册多个 TypeAdapter 的问题~ 它用来标注POJO类,接收一个参数,参数必须是 TypeAdapter,JsonSerializer或 JsonDeserializer 中的一个。
使用方法(以User为例):
使用时不用再 GsonBuilder 去注册 UserTypeAdapter 了。
注:
- @JsonAdapter 仅支持 TypeAdapter 或 TypeAdapterFactory。
- @JsonAdapter 的优先级比 GsonBuilder.registerTypeAdapter 的优先级高。
JsonDeserializer 与 JsonSerializer
那么问题来了,我们只想控制序列化过程或者反序列化过程,比如我们后端经常在我们需要double类型数据时,返回空串””,导致我们数据异常,引起崩溃。肿么办?
同样见名知意, JsonDeserializer 可以用控制反序列化,JsonSerializer 控制序列化。
JsonDeserializer 反序列化操作
|
|
JsonSerializer
|
|
注: registerTypeAdapter
必须使用包装类型,所以 int.class ,long.class,double.class 是不可以的。