gson-GsonBuilder

本文深入探讨了Gson库的高级配置选项,包括排除策略、序列化空字段、类型适配器、字段命名策略等,提供了丰富的代码示例,帮助开发者掌握Gson的进阶使用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

资源贴


描述:当您需要设置默认配置选项以外的配置选项时,请使用此生成器构造Gson实例。对于具有默认配置的Gson,使用new Gson() 更简单。GsonBuilder的最佳用法是创建它,然后调用它的各种配置方法,最后调用create。

1. 默认排除策略

  • excludeFieldsWithModifiers(int… modifiers) 序列化或反序列化排除特定修饰语的字段
  • excludeFieldsWithoutExposeAnnotation()序列化或反序列化排除没有@Expoe的字段前面注解中已经讲述,这边不讲

例子:排除指定修饰器修饰的字段
修饰器可以指定下述这些字段

  • PUBLIC,
  • PROTECTED,
  • PRIVATE,
  • ABSTRACT,
  • DEFAULT,
  • STATIC,
  • FINAL,
  • TRANSIENT,
  • VOLATILE,
  • SYNCHRONIZED,
  • NATIVE,
  • STRICTFP;

默认排除static或transient描述的字段

    public class SomeObject {
        private static String field1;
        private transient String field2;
        private String field3;
        private String field4;
    }
    
    public static void main(String[] args) throws Exception {
        SomeObject someObject = new SomeObject();
        someObject.setField1("field1");
        someObject.setField2("field2");
        someObject.setField3("field3");
        someObject.setField4("field4");
        Gson gson = new GsonBuilder().create();
        System.out.println(gson.toJson(someObject));
    }
    // ==>{"field3":"field3","field4":"field4"}

也可以自己指定排除字段

    public static void main(String[] args) throws Exception {
        SomeObject someObject = new SomeObject();
        someObject.setField1("field1");
        someObject.setField2("field2");
        someObject.setField3("field3");
        someObject.setField4("field4");
        Gson gson = new GsonBuilder().excludeFieldsWithModifiers(Modifier.STATIC).create();
        System.out.println(gson.toJson(someObject));
    }
    // ==>{"field2":"field2","field3":"field3","field4":"field4"}

2. 自定义排除策略

方法:

  • addSerializationExclusionStrategy(ExclusionStrategy strategy) 序列化排除策略
  • addDeserializationExclusionStrategy(ExclusionStrategy strategy) 反序列化排除策略
  • setExclusionStrategies(ExclusionStrategy… strategies) 序列化/反序列化排除策略

例子:序列化过程排除不需要字段

a. 前面讲过的@Expose字段已经可以实现,但是@Expose是加在需要序列化的字段上,假设字段需要序列化的字段多,其它少,这种方式比较麻烦;

b. 自己实现注解,排除不必要字段

注解:

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.FIELD, ElementType.TYPE})
    public @interface GsonTransparent {
    }

策略实现类

   public class GsonTransparentStrategy implements ExclusionStrategy {

   /**
    * 如果注解@GsonTransparent存在排除该字段
    *
    * @param f
    * @return
    */
   @Override
   public boolean shouldSkipField(FieldAttributes f) {
       return f.getAnnotation(GsonTransparent.class) != null;
   }

   /**
    * 如果注解@GsonTransparent存在排除该类
    *
    * @param clazz
    * @return
    */
   @Override
   public boolean shouldSkipClass(Class<?> clazz) {
       return clazz.getAnnotation(GsonTransparent.class) != null;
   }
}

使用方式

  • 注解在字段上,该字段不被序列化或反序列化
  • 注解在类上,该类不被序列化或反序列化
    // 实体类
    public class SomeObject {
        @GsonTransparent
        private String field1;
        private String field2;
        private String field3;
        private String field4;
    }
    
    // 测试
    public static void main(String[] args) throws Exception {
        SomeObject someObject = new SomeObject();
        someObject.setField1("field1");
        someObject.setField2("field2");
        someObject.setField3("field3");
        someObject.setField4("field4");
        // 序列化和反序列化注解都生效
        // 其它两个方法分别对应序列化和反序列化
        Gson gson = new GsonBuilder().setExclusionStrategies(new GsonTransparentStrategy()).create();
        System.out.println(gson.toJson(someObject));
    }
    // ==>{"field2":"field2","field3":"field3","field4":"field4"}

3. 序列化空字段

方法:

  • serializeNulls()

例子:

    public static void main(String[] args) throws Exception {
        SomeObject someObject = new SomeObject();
        someObject.setField1("field1");
        someObject.setField2("field2");
        someObject.setField3("field3");
        Gson gson = new GsonBuilder().serializeNulls().create();
        System.out.println(gson.toJson(someObject));
    }

4. 类型适配器

方法:

  • registerTypeAdapter(java.lang.reflect.Type type, java.lang.Object typeAdapter) 为type类型字段,指定特殊的类型适配器

例子01:格式化日期类型

@JsonAdapter 一样的方式
可以支持 JsonDeserializer,JsonSerializer,InstanceCreator,TypeAdapter四种适配器类型

// 适配器类

public class DateAdapter extends TypeAdapter<Date> {
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

    /**
     * 序列化
     *
     * @param out   输出流
     * @param value 值
     * @throws IOException
     */
    @Override
    public void write(JsonWriter out, Date value) throws IOException {
        if (value != null) {
            out.value(simpleDateFormat.format(value));
        } else {
            out.value("");
        }
    }

    /**
     * 反序列化
     *
     * @param in 输入流
     * @return
     * @throws IOException
     */
    @Override
    public Date read(JsonReader in) throws IOException {
        String str = in.nextString();
        Date date = null;
        try {
            date = simpleDateFormat.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
}

// 测试类

public class Test0020 {
    public static void main(String[] args) throws Exception {
        SomeObject someObject = new SomeObject();
        someObject.setField1("field1");
        someObject.setField2("field2");
        someObject.setField3("field3");
        someObject.setDate(new Date());
        Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new DateAdapter()).serializeNulls().create();
        System.out.println(gson.toJson(someObject));
    }
}

// ==>{"field1":"field1","field2":"field2","field3":"field3","field4":null,"date":"2019-04-15 04:01:35"}

注:如果只是要格式化日期,可以通过
setDateFormat(java.lang.String pattern)设置格式

例子02:String为null转为""输出
// String类型适配器

public class StringAdapter extends TypeAdapter<String> {
    @Override
    public void write(JsonWriter out, String value) throws IOException {
        if (value == null) {
            out.value("");
        } else {
            out.value(value);
        }
    }

    @Override
    public String read(JsonReader in) throws IOException {
        return in.nextString();
    }
}

// 测试类

public class Test0020 {
    public static void main(String[] args) throws Exception {
        SomeObject someObject = new SomeObject();
        someObject.setField1("field1");
        someObject.setField2("field2");
        someObject.setField3("field3");
        someObject.setDate(new Date());
        Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new DateAdapter()).registerTypeAdapter(String.class, new StringAdapter()).serializeNulls().create();
        System.out.println(gson.toJson(someObject));
    }
}
// ==> {"field1":"field1","field2":"field2","field3":"field3","field4":"","date":"2019-04-15 04:03:53"}

5. 字段命名策略

方法:

  • setFieldNamingStrategy(FieldNamingStrategy fieldNamingStrategy)

例子:驼峰转下划线

    public class SomeObject {
        private String helloWord;
    
        public String getHelloWord() {
            return helloWord;
        }
    
        public void setHelloWord(String helloWord) {
            this.helloWord = helloWord;
        }
    }

    public static void main(String[] args) throws Exception {
        SomeObject someObject = new SomeObject();
        someObject.setHelloWord("hello world");
        Gson gson = new GsonBuilder().setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
        System.out.println(gson.toJson(someObject));
    }
    // ==>{"hello_word":"hello world"}

6. 其它相关方法

上述情况包含了我在项目中使用的大多数情况,还有一些方法比较简单可以参看资源贴。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值