Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson 2.1 polymorphic deserialization: How to populate type field on pojo?

Tags:

java

jackson

I am pulling a tree of Categories and Items from a REST service. Categories have a "child" attribute that contains a list of Categories and/or Items. Their types are specified in the field "kind".

Jackson's polymorphic type handling is great and all working as expected, except one small hitch: the "kind" field itself is not populated. Is there a simple way to get this data onto the pojos? I hope not to have to write custom deserializers.

Here is the base class for Category and Item. The two subclasses add several scalar fields, and aren't very interesting.

@JsonIgnoreProperties(ignoreUnknown=true)
@JsonTypeInfo(  
    use = JsonTypeInfo.Id.NAME,  
    include = JsonTypeInfo.As.PROPERTY,  
    property = "kind",
    defaultImpl = EntityBase.Impl.class
    )
@JsonSubTypes({
    @Type(value = Item.class, name = "Item"),  
    @Type(value = Category.class, name = "Category")
    })  
public abstract class EntityBase {
    String title;
    String kind;

    public void setTitle(String title) { this.title = title; }
    public String getTitle() { return title; }

    public void setKind(String kind) { this.kind = kind; }
    public String getKind() { return kind; }

    public static class Impl extends EntityBase {}  
}

I'm doing the deserialization with an ObjectMapper something like this:

ObjectMapper mapper = new ObjectMapper();
Category category = mapper.readValue(inputStream, Category.class);

I think it's so irrelevant that it doesn't even deserve a tag, but just in case, this is in an Android app.

like image 966
dokkaebi Avatar asked Nov 30 '12 02:11

dokkaebi


1 Answers

As usual, I spent a few more minutes searching just before posting this question to make sure I hadn't missed anything obvious.

I wouldn't call it obvious, but I tracked down a resolved jira ticket with the answer. The ticket was linked in comments under a post on http://jackson-users.ning.com/, though I've lost the link to the post.

There is a "visible" attribute on the JsonTypeInfo annotation which does just this.

@JsonTypeInfo(  
    use = JsonTypeInfo.Id.NAME,  
    include = JsonTypeInfo.As.PROPERTY,  
    property = "kind",
    visible = true,                    // <----- add this
    defaultImpl = EntityBase.Impl.class
    )
public abstract class EntityBase {
    ...
}

Turns out, this is documented in the javadocs. I had missed it thanks to the excellent SEO on the old 1.5 docs (and the confusing dichotomy between jackson.codehaus.org and fasterxml.com doesn't help), but now I've learned my lesson and I'm looking at docs here: http://wiki.fasterxml.com/JacksonJavaDocs.

like image 120
dokkaebi Avatar answered Oct 19 '22 17:10

dokkaebi