不能使用(de)序列化具有Jackson中多态项的List

时间:2013-02-22 15:33:17

标签: java json jackson

我有一个问题(de)序列化我没有定义的JSON。

以下是解释此问题的一些代码和JSON:

代码:

public static class Base {
    public String klass = "base";
}

public static class SubBase extends Base {
}

public static class Sub1 extends SubBase {
    public Sub1() {
        klass = "Sub1";
    }
}

public static class Sub2 extends SubBase {
    public Sub2() {
        klass = "Sub2";
    }
}

public static class Holder {
    @JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.WRAPPER_ARRAY, property="type")
    @JsonSubTypes({@JsonSubTypes.Type (name = "sub1", value = Sub1.class),@JsonSubTypes.Type(name = "sub2", value = Sub2.class)})
    public List<Base> items = new ArrayList<Base>();
}


Holder holder = new Holder();
holder.items.add(new Sub1());
holder.items.add(new Sub1());

mapper.writeValueAsString(holder);

产生

{"items":[["sub1",{"klass":"Sub1"}],["sub1",{"klass":"Sub1"}]]}

如果我将JsonTypeInfo注释更改为

    @JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.WRAPPER_OBJECT, property="type")

产生

{"items":[{"sub1":{"klass":"Sub1"}},{"sub1":{"klass":"Sub1"}}]}

到目前为止,一切都很好:)

但是,我从服务器获取的JSON结构略有不同:

{"type":"sub1", "items":[{"klass":"Sub1"},{"klass":"Sub1"}]}

在“type”属性中定义items数组的类型(请注意,“items”数组中的所有项都属于同一类)。
我只是无法弄清楚使用哪个JsonTypeInfo组合来实现这一点。我尝试将'include'设置为“.EXTERNAL_PROPERTY”,但这不起作用 使用这个包含反序列化给了我“线程中的异常”主“org.codehaus.jackson.JsonGenerationException:无法写一个字段名,期望值”错误信息。

我的问题是:我需要使用哪个注释,以便' {“type”:“sub1”,“items”:[{“klass”:“Sub1”},{“klass”:“ Sub1“}]} '将根据Holder的” type “属性为所有Sub1实例填充'items'数组?
如果这是不可能的,还有另一种方法可以实现这一点(不需要Holder的自定义序列化器;只为'items'数组的自定义序列化器会没问题)?

谢谢!

1 个答案:

答案 0 :(得分:5)

无法自动显示您显示的JSON;它不是杰克逊支持的4种类型之一。

如果无法使服务器生成更多标准结构(存在自动支持),则需要编写自定义反序列化器;或者通过两个步骤进行数据绑定,首先进入中间易于映射的结构(如JsonNodeMap),然后从中进入所需的结构,手动提取类型,使用它(例如,使用{ {1}}。