杰克逊 - 多版本领域;回退到默认的反序列化器

时间:2015-08-24 08:48:22

标签: java json jackson deserialization

我有以下类(构造函数,getter,......为了简洁而遗漏):

public static class MetaList {
    @JsonProperty("type")
    private String     type;
    @JsonProperty("items")
    private List<Item> items;
}

public static class Item {
    @JsonProperty("name")
    private String name;
}

public static class Data {
    @JsonProperty("items")
    @JsonDeserialize(using = Deserializer.class)
    private MetaList items;
}

我将List包装到MetaList中,以便能够使用类型注释列表。 Data类的示例JSON如下:

{
    "items": {
        "type": "DELTA",
        "items": [
            {
                "name": "item 1"
            },
            {
                "name": "item 2"
            }
        ]
    }
}

我希望能够解析以下输入:

{
    "items": [
        {
            "name": "item 1"
        },
        {
            "name": "item 2"
        }
    ]
}

在这种情况下,没有给出类型。我不希望用户费心将项目列表包装在项目对象中。

我开始创建自己的反序列化器:

public static class Deserializer extends JsonDeserializer<MetaList> {
    @Override
    public MetaList deserialize(final JsonParser parser, final DeserializationContext context) throws IOException {
        final JsonToken token = parser.getCurrentToken();

        if (JsonToken.START_ARRAY.equals(token)) {
            return new MetaList(null, ... QUESTION ...);
        } else if (JsonToken.START_OBJECT.equals(token)) {
            return ... QUESTION ...
        }
        throw context.mappingException(MetaList.class);
    }
}

在第一个if中,用户提供了短版本(没有类型)。在第二个if中,用户提供了长版本(带有类型)。

如何在我的反序列化程序中访问List(第一个if)或MetaList(第二个if)的默认序列化程序?我相信默认反序列化器的简单回退完成了实现。

1 个答案:

答案 0 :(得分:1)

实际上非常简单:

public static class Deserializer extends JsonDeserializer<MetaList> {
    @Override
    public MetaList deserialize(final JsonParser parser, final DeserializationContext context) throws IOException {
        final JsonToken token= parser.getCurrentToken();

        if (JsonToken.START_ARRAY.equals(token)) {
            return new MetaList(null, (List) context.findRootValueDeserializer(context.constructType(List.class)).deserialize(parser, context));
        } else if (JsonToken.START_OBJECT.equals(token)) {
            return (MetaList) context.findRootValueDeserializer(context.constructType(MetaList.class)).deserialize(parser, context);
        }
        throw context.mappingException(MetaList.class);
    }
}