Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Duplicate JSON Field with Jackson

Tags:

java

json

jackson

I solved this by using the JsonTypeInfo.As.EXISTING_PROPERTY in the @JsonTypeInfo annotation.

The project is open source, check it out here: ANS.java


I was having this exact same problem with the duplicate output. I found a solution that did not involve another property, and allowed me to not remove the original property. First, I set the visible flag to true for JsonTypeInfo. Then, I added a JsonIgnore annotation to the property declaration and the getter (but not the setter). This is so far outputting the JSON correctly with only one key for the type property.

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, visible = true, property = "mimeType")
@JsonSubTypes({
    @JsonSubTypes.Type(value = ImageBookmarkJsonModel.class, name = "image/jpeg"),
    @JsonSubTypes.Type(value = EpubBookmarkJsonModel.class, name = "application/epub+zip")
})
public abstract class AbstractBookmarkJsonModel extends AbstractJsonModel {
    @JsonIgnore
    @JsonProperty("mimeType")
    protected String mimeType;

    @JsonIgnore
    @JsonProperty("mimeType")
    public String getMimeType() {
        return mimeType;
    }

    @JsonProperty("mimeType")
    public void setMimeType(String mimeType) {
        this.mimeType = mimeType;
    }

}

To note, this is with fasterxml jackson jackson-databind 2.1.1

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.1.1</version>
</dependency>

This behaviour is caused by the annotations placed on class AbstractBookmarkJsonModel:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "mimeType")
@JsonSubTypes({
    @JsonSubTypes.Type(value = ImageBookmarkJsonModel.class, name = "image/jpeg"),
    @JsonSubTypes.Type(value = EpubBookmarkJsonModel.class, name = "application/epub+zip")
})

@JsonTypeInfo tells Jackson to serialize the logical type name (JsonTypeInfo.Id.NAME) as a property (JsonTypeInfo.As.PROPERTY) with name mimeType (property = "mimeType"). With @JsonSubTypes.Type you assign the logical name application/epub+zip to EpubBookmarkJsonModel.

When it comes to serialization, Jackson serializes the logical name as a property mimeType = "application/epub+zip" then the properties of the object among them mimeType which happens to have the same value as the logical name application/epub+zip (assigned in the constructor).

I think mimeType should be changed to objectType in the @JsonTypeInfo annotation or even better to remove the mimeType field since Jackson will take care of that through type info serialization.