I want to deserialize a piece of JSON using Jackson 2.x.
There's json that looks like this:
{
"response":[
230,
{
"id":1627,
"from_id":4534,
"attachments":[
{
"type":"audio",
"audio":{
"aid":25918,
"owner_id":20000,
}
},
{
"type":"link",
"link":{
"url":"http://lenta.ru",
"title":"bla"
}
}
]
}
...
]
}
So I want to use Polymorphic Type Handling to deserialize attachments into List of Attachment's. I have following POJOs with Mixins:
public class Post {
private final String id;
private List<? extends Attachment> attachments;
// ...
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class PostMixin {
@JsonProperty("id")
String id;
@JsonProperty("attachments")
List<? extends Attachment> attachments;
// ...
}
public abstract class Attachment {
public static enum AttachmentType {
AUDIO, LINK
}
private AttachmentType type;
public AttachmentType getType() {
return type;
}
}
// Not sure here if using these annotations propper way
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME,
include=JsonTypeInfo.As.PROPERTY, property = "type", visible = true)
@JsonSubTypes({
@JsonSubTypes.Type(name="link", value=LinkAttachment.class),
@JsonSubTypes.Type(name="audio", value=AudioAttachment.class)
})
@JsonIgnoreProperties(ignoreUnknown = true)
public class AttachmentMixin {
@JsonProperty("type")
@JsonDeserialize(using = AttachmentTypeDeserializer.class)
Attachment.AttachmentType type;
// parse type into enum
private static class AttachmentTypeDeserializer extends
JsonDeserializer<Attachment.AttachmentType> {
@Override
public Attachment.AttachmentType deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
return Attachment.AttachmentType.valueOf(jp.getText().toUpperCase());
}
}
}
public class LinkAttachment extends Attachment {
private String url;
private String title;
public String getUrl() {
return url;
}
public String getTitle() {
return title;
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class LinkAttachmentMixin extends AttachmentMixin {
@JsonProperty("url")
String url;
@JsonProperty("title")
String title;
}
public class AudioAttachment extends Attachment {
private String id;
private String ownerId;
public String getId() {
return id;
}
public String getOwnerId() {
return ownerId;
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
public class AudioAttachmentMixin extends AttachmentMixin {
@JsonProperty("aid")
private String id;
@JsonProperty("owner_id")
private String ownerId;
}
Created module to register Mixins:
public class MyModule extends SimpleModule {
public MyModule() {
super("MyModule");
}
@Override
public void setupModule(SetupContext context) {
context.setMixInAnnotations(Post.class, PostMixin.class);
context.setMixInAnnotations(Attachment.class, AttachmentMixin.class);
context.setMixInAnnotations(LinkAttachment.class, LinkAttachmentMixin.class);
context.setMixInAnnotations(AudioAttachment.class,AudioAttachmentMixin.class);
}
}
Initialize ObjectMapper:
objectMapper = new ObjectMapper();
objectMapper.registerModule(new MyModule());
When I try to deserialize JSON I get following exception:
java.lang.IllegalArgumentException: Class my.package.LinkAttachmentMixin is not assignable to my.package.Attachment
(through reference chain: my.package.Post["attachments"])
Is it possible to deserialize this JSON with Jackson Polymorphic Type Handling support? Do I need to write my own deserializers? Can someone give a good sample to start with? Is it possible at all to parse this JSON using annotations only?
Try putting the @JsonTypeInfo
and @JsonSubTypes
annotations on your Attachment
class instead of on the mixin. You might even be able to eliminate the mixins entirely by annotating the other classes properly. If you go that road then you'll probably have to annotate your VO classes/attributes and the AttachmentType with @JsonCreator
.
Here's an article that describes deserialization similar to what you're trying to do. I've found it useful in the past for doing this sort of thing.
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