简体   繁体   中英

jackson - multi version field; fallback to default deserializer

I have the following classes (constructors, getters, ... left out for brevity):

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;
}

I am wrapping a List into a MetaList to be able to annotate the list with a type. An example JSON for the Data class is as following:

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

I would like to be able to also parse the following input:

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

In this case, no type is given. I don't want the user to bother to wrap his item list in an items object.

I started with creating my own deserializer:

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);
    }
}

In the first if , the user is giving the short version (without the type). In the second if , the user is giving the long version (with the type).

How can I access the default serializer for List (first if ) or MetaList (second if ) in my deserializer? I believe that a simple fallback to the default deserializer finishes the implementation.

It was actually quite simple:

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);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM