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 会崩溃! 尽管如此,这应该为我们提供一个多态对象列表的自动映射,只需要很少的代码行。

免责声明:
1.本站所有内容由本站原创、网络转载、消息撰写、网友投稿等几部分组成。
2.本站原创文字内容若未经特别声明,则遵循协议CC3.0共享协议,转载请务必注明原文链接。
3.本站部分来源于网络转载的文章信息是出于传递更多信息之目的,不意味着赞同其观点。
4.本站所有源码与软件均为原作者提供,仅供学习和研究使用。
5.如您对本网站的相关版权有任何异议,或者认为侵犯了您的合法权益,请及时通知我们处理。
火焰兔 » Gson 如何反序列化多态对象列表