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 会崩溃! 尽管如此,这应该为我们提供一个多态对象列表的自动映射,只需要很少的代码行。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布,任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站。本站所有源码与软件均为原作者提供,仅供学习和研究使用。如您对本站的相关版权有任何异议,或者认为侵犯了您的合法权益,请及时通知我们处理。