【问题标题】:jackson de-serializing polymorphic types杰克逊反序列化多态类型
【发布时间】:2013-01-04 19:55:43
【问题描述】:

我有以下示例类:

class Zoo {
    public Collection<? extends Animal> animals;
}

在序列化时,我尝试尽可能多地序列化类型信息:

  mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

我得到以下 JSON:

[
    "com.bp.samples.json.generics.Zoo",
    {
        "animals": [
            "java.util.ArrayList",
            [
                [
                    "com.bp.samples.json.generics.Bird",
                    {
                        "name": "bird-1",
                        "wingSpan": "6 feets",
                        "preferredFood": "food-1"
                    }
                ],
                [
                    "com.bp.samples.json.generics.Cat",
                    {
                        "name": "cat-1",
                        "favoriteToy": "toy-1"
                    }
                ],
                [
                    "com.bp.samples.json.generics.Dog",
                    {
                        "name": "dog-1",
                        "breed": "bread-1",
                        "leashColor": "black"
                    }
                ]
            ]
        ]
    }
]

说到反序列化,尝试做:

mapper.readValue(new File("./DataFiles/Zoo-2.json"), Zoo.class);

导致以下异常:

Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: 
Can not deserialize instance of com.bp.samples.json.generics.Zoo out of START_ARRAY toke

并尝试做:

mapper.readValue(new File("./DataFiles/Zoo-2.json"), 
   new TypeReference<Collection<? extends Animal>>() {});

结果:

Can not construct instance of com.bp.samples.json.generics.Animal, 
problem: abstract types either need to be mapped to concrete types, have custom 
deserializer, or be instantiated with additional type information
at [Source: ./DataFiles/Zoo-2.json; line: 2, column: 5]

当然,编写自定义反序列化程序可以解决问题,但是如果没有自定义反序列化程序就可以进行反序列化吗?

谢谢, 贝扎德

【问题讨论】:

  • 将 JSON 数组(集合)反序列化为 Java 对象(Zoo -- 这不是集合)将不起作用(没有特殊处理)。您是否必须使用 DefaultTyping 来提供类型信息?您可能想在programmerbruce.blogspot.com/2011/05/… 上查看完整的多态反序列化示例
  • 我建议你选择一个标签来替换为java(让问题更加关注)。
  • @Programmer_Bruce 我认为这里的数组是由于包含默认类型信息,所以应该没问题。

标签: java json generics polymorphism jackson


【解决方案1】:

据我所知,您的第一次尝试应该会奏效。我能想到的唯一解释是您尝试使用不同配置的 ObjectMapper 进行反序列化:两者都必须以相同的方式启用默认类型(因为这是控制是否包含类型信息的原因)。

如果您使用相同的映射器实例(或相同的配置),您可能需要提交错误报告以便诊断和修复问题。

【讨论】:

  • 谢谢大家的回答。我只是认为在反序列化时,它应该看到类型信息并在没有启用它的情况下使用它。所以,无论如何,我在反序列化时丢失了:“mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL)”。谢谢你
  • 不,没有可靠的方法可以知道任意 JSON 对象或数组是否代表 Java 对象或类型信息包装器——并且由于模棱两可,设置必须匹配。
【解决方案2】:

确保您为用于反序列化的 ObjectMapper 实例启用了类型信息。你想反序列化到 Zoo 而不是 Collection of Animals,所以第一个代码片段是对的。

您可能还想试试Genson lib。 我刚刚用它检查了你的例子,一切似乎都很好。 要在 Genson 中启用多态类型支持,您需要配置您的 genson 实例:

Genson genson = new Genson.Builder().setWithClassMetadata(true).create();

【讨论】:

    猜你喜欢
    • 2012-12-22
    • 1970-01-01
    • 2015-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多