10

我有一个问题(反)序列化我没有定义的 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"}]}

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

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

谢谢!

4

1 回答 1

5

无法自动映射您显示的 JSON;它不是 Jackson 支持的 4 种类型之一。

如果你不能让服务器产生更标准的结构(有自动支持),你需要编写一个自定义的反序列化器;或分两步进行数据绑定,首先进入一个易于映射的中间结构(如JsonNodeor Map),然后使用该结构手动提取类型(例如,使用ObjectMapper.convertValue(object, resultType).

于 2013-02-22T18:34:19.990 回答