I have got the following sample class:
class Zoo {
public Collection<? extends Animal> animals;
}
When serializing, I am trying to serialize as much as type information as I can by doing:
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
And I get the following JSON:
[
"com.bp.samples.json.generics.Zoo",
{
"animals": [
"java.util.ArrayList",
[
[
"com.bp.samples.json.generics.Bird",
{
"name": "bird-1",
"wingSpan": "6 feets",
"preferredFood": "food-1"
}
],
[
"com.bp.samples.json.generics.Cat",
{
"name": "cat-1",
"favoriteToy": "toy-1"
}
],
[
"com.bp.samples.json.generics.Dog",
{
"name": "dog-1",
"breed": "bread-1",
"leashColor": "black"
}
]
]
]
}
]
When it comes to de-serializing, trying to do:
mapper.readValue(new File("./DataFiles/Zoo-2.json"), Zoo.class);
results in the following exception:
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException:
Can not deserialize instance of com.bp.samples.json.generics.Zoo out of START_ARRAY toke
and trying to do:
mapper.readValue(new File("./DataFiles/Zoo-2.json"),
new TypeReference<Collection<? extends Animal>>() {});
results in:
Can not construct instance of com.bp.samples.json.generics.Animal,
problem: abstract types either need to be mapped to concrete types, have custom
deserializer, or be instantiated with additional type information
at [Source: ./DataFiles/Zoo-2.json; line: 2, column: 5]
Writing a custom de-serializer, off course, solves the problem, but is there away to de-serialize without a custom de-serializer?
Thanks, Behzad
Your first attempt should work as far as I can see. The only explanation I can think of would be that you are trying to use differently configured ObjectMapper for deserialization: both MUST have default typing enabled in the same way (since this is what controls whether type information is included or not).
If you are using the same mapper instance (or identically configured), you may want to file a bug report so the problem gets diagnosed and fixed.
Make sur that you enabled type informations for the ObjectMapper instance you use to deserialize. You want to deserialize to Zoo not to Collection of Animals, so the first code snipet is right.
You might also want to try Genson lib. I just checked your example with it, and everything seems to work fine. To enable polymorphic types support in Genson you need to configure your genson instance:
Genson genson = new Genson.Builder().setWithClassMetadata(true).create();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With