Ich möchte ein Stück JSON mit Jackson 2.x deserialisieren.Tricky (?) JSON, polymorphe Deserialisierung
Es json ist, die wie folgt aussieht:
{
"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"
}
}
]
}
...
]
}
Deshalb möchte ich Polymorphe Typ Handhabung verwenden Anhänge deserialisieren in Liste der Befestigung des. Ich habe folgende POJOs mit 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;
}
Erstellt Modul registrieren 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);
}
}
initialisieren ObjectMapper:
objectMapper = new ObjectMapper();
objectMapper.registerModule(new MyModule());
Wenn ich versuche, JSON deserialisieren ich folgende Ausnahme erhalten:
java.lang.IllegalArgumentException: Class my.package.LinkAttachmentMixin is not assignable to my.package.Attachment
(through reference chain: my.package.Post["attachments"])
Ist es möglich, dieses JSON mit Jackson Polymorphic Type zu deserialisieren? Muss ich meine eigenen Deserializer schreiben? Kann jemand ein gutes Beispiel geben, um damit zu beginnen? Ist es überhaupt möglich, diesen JSON nur mit Anmerkungen zu analysieren?
Leicht zu deserialisieren "manuell". Jackson macht es kompliziert. –
Ihr geposteter Code bezieht sich nicht auf 'PageAttachmentMixin' irgendwo, ist dies die richtige Klasse? – Nachi
@Nachi yep, das war ein Tippfehler, denn ich habe versucht, den Code zu vereinfachen. – vkolodrevskiy