MiketheCalamity
MiketheCalamity

Reputation: 1269

jackson - Deserialize object with a list of polymorphic types

I think it's best to explain with an example.

I have a JSON object I want to deserialize that contains a list of type interface and which type is in the list, but I'm not sure how to get the deserializer to determine which concrete type is in the list:

Type to deserialize

public class MyClass {
    private MyEnum type; // A or B
    private List<Parent> objects;
}

Interface

public interface Parent

Children

public ChildA implements Parent
public ChildB implements Parent


I know I can use the type with JsonSubTypes with the type if it wasn't a List, such as:

@JsonTypeInfo(use = Id.NAME, include = As.EXISTING_PROPERTY, property = "type", visible = true)
@JsonSubTypes({
        @JsonSubTypes.Type(value = ChildA.class, name = "A"),
        @JsonSubTypes.Type(value = ChildB.class, name = "B")
})

And the same thing if type is inside the Parent type. But is there a way to assist the deserializer in determining the type in the list when the type is outside the Parent class? (the list will only ever contain one child type)

Upvotes: 2

Views: 1845

Answers (1)

Alex Taylor
Alex Taylor

Reputation: 8813

Jackson struggles with type erasure on collections with JsonTypeInfo (Here's a Jackson Scala bug report). However, arrays are strongly typed so if possible, you could switch to using an array instead. It seems the simplest way.

Alternatively, writing a smart JsonDeserializer capable of instantiating the correct class could be used with the @JsonDeserialize(contentUsing=...) annotation. Internally, the deserializer could still fall back to using Jackson's readValue method. So it really would be just responsible for choosing the correct type. This answers of this question give examples of reverting to standard deserialization from a custom deserializer.

Upvotes: 1

Related Questions