本次的主要内容

  • Gson 的流式反序列化
  • Gson 的流式序列化
  • 使用 GsonBuilder 导出 null 值、格式化输出、日期时间及其它小功能

一、Gson 的流式反序列化

1.1 自动方式

Gson 提供了 fromJson()toJson() 两个直接用于解析和生成的方法,前者实现反序列化,后者实现了序列化。同时每个方法都提供了重载方法,我常用的总共有5个。

这是我在上一篇文章开头说的,但我到最后也一直没有是哪5个,这次我给列出来之后,你就知道这次讲的是哪个了。

  1. Gson.toJson(Object);
  2. Gson.fromJson(Reader, Class);
  3. Gson.fromJson(String, Class);
  4. Gson.fromJson(Reader, Type);
  5. Gson.fromJson(String, Type);

好了,本节结束!
Gson 使用指南(二) - 图1
看第2、4行,Reader 懂了吧!

1.2 手动方式

手动的方式就是使用 stream 包下的 JsonReader 类来手动实现反序列化,和 Android 中使用 pull 解析 XML 是比较类似的。

  1. String json = "{\"name\":\"怪盗kidou\",\"age\":\"24\"}";
  2. User user = new User();
  3. JsonReader reader = new JsonReader(new StringReader(json));
  4. reader.beginObject(); // throws IOException
  5. while (reader.hasNext()) {
  6. String s = reader.nextName();
  7. switch (s) {
  8. case "name":
  9. user.name = reader.nextString();
  10. break;
  11. case "age":
  12. user.age = reader.nextInt(); //自动转换
  13. break;
  14. case "email":
  15. user.email = reader.nextString();
  16. break;
  17. }
  18. }
  19. reader.endObject(); // throws IOException
  20. System.out.println(user.name); // 怪盗kidou
  21. System.out.println(user.age); // 24
  22. System.out.println(user.email); // ikidou@example.com

其实自动方式最终都是通过 JsonReader 来实现的,如果第一个参数是 String 类型,那么 Gson 会创建一个 StringReader 转换成流操作。
Gson 使用指南(二) - 图2
Gson 流式解析

二、Gson 的流式序列化

2.1 自动方式

Gson 使用指南(二) - 图3
Gson.toJson 方法列表
所以啊,学会利用 IDE 的自动完成是多么重要这下知道了吧!可以看出用红框选中的部分就是我们要找的东西。

提示:PrintStream(System.out)StringBuilderStringBuffer*Writer 都实现了 Appendable 接口。

  1. Gson gson = new Gson();
  2. User user = new User("怪盗kidou",24,"ikidou@example.com");
  3. gson.toJson(user,System.out); // 写到控制台

2.2 手动方式

  1. JsonWriter writer = new JsonWriter(new OutputStreamWriter(System.out));
  2. writer.beginObject() // throws IOException
  3. .name("name").value("怪盗kidou")
  4. .name("age").value(24)
  5. .name("email").nullValue() // 演示 null
  6. .endObject(); // throws IOException
  7. writer.flush(); // throws IOException
  8. // ==> {"name":"怪盗kidou","age":24,"email":null}

提示:除了 beginObjectendObject 还有 beginArrayendArray,两者可以相互嵌套,注意配对即可。beginArray 后不可以调用 name 方法,同样 beginObject 后在调用 value 之前必须要调用 name 方法。

三、 使用 GsonBuilder 导出 null 值、格式化输出、日期时间

一般情况下 Gson 类提供的 API 已经能满足大部分的使用场景,但我们需要更多更特殊、更强大的功能时,这时候就引入一个新的类 GsonBuilder

GsonBuilder 从名上也能知道是用于构建 Gson 实例的一个类,要想改变 Gson 默认的设置必须使用该类配置 Gson

3.1 GsonBuilder 的用法

  1. Gson gson = new GsonBuilder()
  2. // 各种配置
  3. .create(); // 生成配置好的 Gson

Gson 在默认情况下是不动导出值 null 的键的,如:

  1. public class User {
  2. // 省略其它
  3. public String name;
  4. public int age;
  5. public String email;
  6. }
  1. Gson gson = new Gson();
  2. User user = new User("怪盗kidou",24);
  3. System.out.println(gson.toJson(user));
  4. // ==> {"name":"怪盗kidou","age":24}

可以看出,email 字段是没有在 JSON 中出现的,当我们在调试是、需要导出完整的 JSON 串时或 API 接中要求没有值必须用 Null 时,就会比较有用。

使用方法:

  1. Gson gson = new GsonBuilder()
  2. .serializeNulls()
  3. .create();
  4. User user = new User("怪盗kidou", 24);
  5. System.out.println(gson.toJson(user));
  6. // ==> {"name":"怪盗kidou","age":24,"email":null}

3.3 格式化输出、日期时间及其它

这些都比较简单就不一一分开写了。

  1. Gson gson = new GsonBuilder()
  2. // 序列化 null
  3. .serializeNulls()
  4. // 设置日期时间格式,另有2个重载方法
  5. // 在序列化和反序化时均生效
  6. .setDateFormat("yyyy-MM-dd")
  7. // 禁此序列化内部类
  8. .disableInnerClassSerialization()
  9. // 生成不可执行的 JSON(多了 )]}' 这4个字符)
  10. .generateNonExecutableJson()
  11. // 禁止转义 HTML 标签
  12. .disableHtmlEscaping()
  13. // 格式化输出
  14. .setPrettyPrinting()
  15. .create();

注意:内部类(Inner Class)和嵌套类(Nested Class)的区别。