Gson 如何反序列化多态对象列表
最近,我们遇到了一种情况,我从 REST 端点接收到 JSON 格式的对象列表。 到目前为止,这没有什么不寻常的,也不是问题。 然而,问题是对象是多态的,需要解析子类特定的字段。 以前的解决方案是手动解析它。 对我们来说,这是不可接受的,我正在寻找更好的解决方案。 因为我们已经在使用 Gson,所以我希望有一个技巧可以让它与 Gson 一起工作。 不幸的是,大多数人建议编写一个自定义的反序列化器,这仍然比手动编写要好,但代码也很多。 最后,我找到了 RuntimeTypeAdapterFactory
类,它很好地解决了这个问题。
让我们假设项目使用以下类:
public class Animal {
private String name;
private String type; // 这指定了它是哪种动物
}
public class Dog extends Animal {
private boolean playsCatch;
}
public class Cat extends Animal {
private boolean chasesRedLaserDot;
}
}
想象一下,我们会得到一个 Animal-Objects 列表,其中包含随机的子类。 有几只狗,有几只猫,没有特别的顺序。
如何解决
正如介绍中提到的,RuntimeTypeAdapterFactory
类就是解决方案。 它不附带 Gson 包,因此我们必须下载并将其手动添加到项目中。
接下来,我们设置映射。
String responseJson = new String(responseBody); // 从服务端获取的数据
// 哪种格式有服务器的响应
final TypeToken<ServiceResponse> requestListTypeToken = new TypeToken<ServiceResponse>() {};
// 添加所有不同的容器类及其标志
final RuntimeTypeAdapterFactory<AbstractContainer> typeFactory = RuntimeTypeAdapterFactory
.of(Animal.class, "type") // 在指定哪个是父类以及哪个字段具体化子类时。
.registerSubtype(Dog.class, "dog") // 如果标志等于类名,则可以跳过第二个参数。 只有在“类型”字段不等于类名时才需要这样做。
.registerSubtype(Cat.class, "cat");
final Gson gson = new GsonBuilder().registerTypeAdapterFactory(typeFactory).create();
// 映射
final ServiceResponse deserializedRequestList = gson.fromJson(responseJson, requestListTypeToken.getType() );
请注意,如果服务返回了意料之外的类型,例如 Horse,Gson 会崩溃! 尽管如此,这应该为我们提供一个多态对象列表的自动映射,只需要很少的代码行。
相关文章
Gson 通过@JsonAdapter 自定义(反)序列化
发布时间:2022/07/24 浏览次数:217 分类:编程语言
-
在这篇文章中,我们将展示如何简化(反)序列化的自定义。 所有这些选项都只能通过自定义 Gson 实例和一些样板代码获得。 Gson 2.7 引入了一个简单的注解,我们可以节省大量代码并获
Gson 自定义反序列化基础
发布时间:2022/07/21 浏览次数:81 分类:编程语言
-
在这篇文章中,我们将了解如何实现自定义 Gson 反序列化。 如果服务器以与客户端的应用程序数据模型不匹配的格式向我们发送数据,请继续阅读!
Gson 自定义实例创建器
发布时间:2022/07/14 浏览次数:121 分类:编程语言
-
在这篇文章中,我们将讨论自定义反序列化的另一个组件。 在过去的几篇文章中,我们探讨了如何自定义数据的序列化和反序列化。 在这两种情况下,我们都试图减轻服务器和客户端之
Gson 循环引用的映射
发布时间:2022/07/13 浏览次数:173 分类:编程语言
-
在这篇文章中,我们将讨论一个特别讨厌的话题:循环引用。 我们可能在计算机科学或图表数学课上听说过循环引用。 在更实际的解释中:它处理对象具有指向不同对象的嵌套属性的情
Gson Builder Floats 和 Doubles 的特殊值
发布时间:2022/07/12 浏览次数:193 分类:编程语言
-
在上一篇 Gson 的文章中,我们研究了使 JSON 转换降低标准的选项。 Lenient 允许传入的 JSON 在某种程度上是非标准的,Gson 仍然能够将其解析为 Java 对象。 在这篇文章中,我们将研究一个
Gson 自定义序列化
发布时间:2022/07/11 浏览次数:117 分类:编程语言
-
在这篇文章中,我们将探讨如何自定义 Java 对象的 Gson 序列化。 我们可能想要更改序列化的原因有很多,例如 简化我们的模型以减少发送的数据量或删除个人信息。 现在我们将通过实
Gson 映射 Enum 枚举
发布时间:2022/07/10 浏览次数:156 分类:编程语言
-
在之前的文章中我们介绍了如何映射嵌套对象、数组和列表、Java Map 等。 在这篇文章中,您将学习如何(反)序列化 Java 枚举 Enum。
Gson Builder 使用 Lenient 放宽 Gson 的转换标准
发布时间:2022/06/26 浏览次数:100 分类:编程语言
-
JSON 内容的格式必须满足一些特定的规则才能符合标准。 该标准在 RFC4627 规范中进行了描述。 它为键和值的分离方式、数组的结构等奠定了基础。 在这篇文章中,我们将探讨 Gson 与 J