棘手(?)JSON,多态反序列化 [英] Tricky(?) JSON, polymorphic deserialization

查看:274
本文介绍了棘手(?)JSON,多态反序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用Jackson 2.x反序列化一段JSON。

I want to deserialize a piece of JSON using Jackson 2.x.

这里的json是这样的:

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"
               }
            }
         ]
      }
      ...
   ]
}

所以我想使用多态类型处理来将附件反序列化
到附件列表中。
我跟随Mixins使用以下POJO:

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;
}

创建模块以注册Mixins:

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);
    }
}

初始化ObjectMapper:

Initialize ObjectMapper:

objectMapper = new ObjectMapper();
objectMapper.registerModule(new MyModule());

当我尝试反序列化JSON时,我得到以下异常:

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"])

是否可以使用Jackson Polymorphic Type反序列化此JSON
处理支持?
我需要编写自己的反序列化器吗?有人可以给一个好的
样本开始吗?
是否可以仅使用注释解析此JSON?

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?

推荐答案

尝试输入 @JsonTypeInfo @JsonSubTypes 注释附件类而不是mixin上的注释。您甚至可以通过正确地注释其他类来完全消除mixins。如果你走那条路,那么你可能需要用 @JsonCreator 来注释你的VO类/属性和AttachmentType。

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.

这篇关于棘手(?)JSON,多态反序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆