棘手的(?)JSON,多态反序列化

棘手的(?)JSON,多态反序列化,json,jackson,deserialization,polymorphism,Json,Jackson,Deserialization,Polymorphism,我想使用Jackson 2.x反序列化一段JSON 有一个json看起来像这样: { "response":[ 230, { "id":1627, "from_id":4534, "attachments":[ { "type":"audio", "audio":{ "aid":25918,

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

有一个json看起来像这样:

{
     "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"
               }
            }
         ]
      }
      ...
   ]
}
所以我想使用多态类型处理来反序列化附件 进入附件的列表。 我有以下带有混音器的POJO:

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;
}
初始化ObjectMapper:

objectMapper = new ObjectMapper();
objectMapper.registerModule(new MyModule());
当我尝试反序列化JSON时,出现以下异常:

java.lang.IllegalArgumentException: Class my.package.LinkAttachmentMixin is not assignable to my.package.Attachment
(through reference chain: my.package.Post["attachments"])
是否可以使用Jackson多态类型反序列化此JSON 处理支持? 我是否需要编写自己的反序列化程序?有人能给我一个好机会吗 首先是什么样的?
是否可以仅使用注释解析此JSON

尝试将
@JsonTypeInfo
@JsonSubTypes
注释放在
附件上,而不是放在mixin上。您甚至可以通过正确地注释其他类来完全消除mixin。如果您走这条路,那么您可能必须使用
@JsonCreator
注释VO类/属性和AttachmentType


这描述了与您尝试执行的操作类似的反序列化。我发现它在过去做这种事情很有用。

很容易“手动”反序列化。Jackson让事情变得复杂了。你发布的代码没有引用
PageAttachmentMixin
任何地方,这是正确的类吗?@Nachi yep,这是一个拼写错误,因为我试图简化代码。我不理解你的JSON。您有
response
数组,其中第一个元素是number,第二个元素是POJO,是吗?可以吗?应该是这样吗?
java.lang.IllegalArgumentException: Class my.package.LinkAttachmentMixin is not assignable to my.package.Attachment
(through reference chain: my.package.Post["attachments"])