I'm using @JsonTypeInfo and @JsonSubTypes to map parsing subclasses based on a given property. Here's a contrived example of my sample JSON that I want to parse.
{ "animals": [
{ "type" : "dog", "name" : "spike" }
,{ "type" : "cat", "name" : "fluffy" }
]}
Using this as the class
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME
,include = JsonTypeInfo.As.PROPERTY
,property = "type")
@JsonSubTypes({
@Type(value = Cat.class, name = "cat"),
@Type(value = Dog.class, name = "dog") })
abstract class Animal {
public String name;
{
class Dog extends Animal { }
class Cat extends Animal { }
However, the problem occurs when the JSON contains type that I would want to ignore. For example, if I have a new type "pig" that I don't really want to deserialize as an object:
{ "animals": [
{ "type" : "dog", "name" : "spike" }
,{ "type" : "cat", "name" : "fluffy" }
,{ "type" : "pig", "name" : "babe" }
]}
and try to parse it, it will give me this error:
Could not resolve type id 'pig' into a subtype of [simple type, class Animal]
How can I fix it so that I can map only those animals of type 'dog' and 'cat', and ignore everything else?
You can avoid exception by setting the JsonTypeInfo.defaultImpl annotation attibute to java.lang.Void or NoClass depending on the Jackson version you are using.
Here is an example:
public class JacksonUnknownType {
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type", defaultImpl = Void.class)
@JsonSubTypes({
@JsonSubTypes.Type(value = Cat.class, name = "cat"),
@JsonSubTypes.Type(value = Dog.class, name = "dog")})
public abstract static class Animal {
public String name;
@Override
public String toString() {
return getClass().getName() + " :: " + name;
}
}
public static class Dog extends Animal {
}
public static class Cat extends Animal {
}
public static final String JSON = "[\n" +
" { \"type\" : \"dog\", \"name\" : \"spike\" }\n" +
" ,{ \"type\" : \"cat\", \"name\" : \"fluffy\" }\n" +
" ,{ \"type\" : \"pig\", \"name\" : \"babe\" }\n" +
"]";
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
List<Animal> value = mapper.readValue(JSON, new TypeReference<List<Animal>>() {});
System.out.println(value);
}
}
Output:
[stackoverflow.JacksonUnknownType$Dog :: spike, stackoverflow.JacksonUnknownType$Cat :: fluffy, null, null, null]
Note that the resulting collection contains 3 null items instead of 1. This may be a bug in Jackson but it is easy to tolerate.
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