Reputation:
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.
Upvotes: 0
Views: 1597
Reputation:
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);
}
}
Upvotes: 2