Java:Jackson 多态 JSON 反序列化具有接口属性的对象?

我正在使用Jackson's来反序列化包含接口作为其属性之一的对象的JSON表示形式。可以在此处查看代码的简化版本:ObjectMapper

https://gist.github.com/sscovil/8735923

基本上,我有一个具有两个属性的类:和.JSON 模型如下所示:Assettypeproperties

{
    "type": "document",
    "properties": {
        "source": "foo",
        "proxy": "bar"
    }
}

该属性被定义为一个名为 的接口,我有几个类来实现它(例如, )。这个想法是图像文件具有与文档文件等不同的属性(高度,宽度)。propertiesAssetPropertiesDocumentAssetPropertiesImageAssetProperties

我已经研究了本文中的示例,通读了SO及其他内容的文档和问题,并在注释参数中尝试了不同的配置,但无法破解这个螺母。任何帮助将不胜感激。@JsonTypeInfo

最近,我得到的例外是这样的:

java.lang.AssertionError: Could not deserialize JSON.
...
Caused by: org.codehaus.jackson.map.JsonMappingException: Could not resolve type id 'source' into a subtype of [simple type, class AssetProperties]

提前致谢!

溶液:

非常感谢@Micha ł Ziober,我能够解决这个问题。我还能够使用枚举作为类型ID,这需要一些谷歌搜索。以下是带有工作代码的更新的要点:

https://gist.github.com/sscovil/8788339


答案 1

您应该使用 代替 。在此方案中,您的类应如下所示:JsonTypeInfo.As.EXTERNAL_PROPERTYJsonTypeInfo.As.PROPERTYAsset

class Asset {

    @JsonTypeInfo(
            use = JsonTypeInfo.Id.NAME,
            include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
            property = "type")
    @JsonSubTypes({
        @JsonSubTypes.Type(value = ImageAssetProperties.class, name = "image"),
        @JsonSubTypes.Type(value = DocumentAssetProperties.class, name = "document") })
    private AssetProperties properties;

    public AssetProperties getProperties() {
        return properties;
    }

    public void setProperties(AssetProperties properties) {
        this.properties = properties;
    }

    @Override
    public String toString() {
        return "Asset [properties("+properties.getClass().getSimpleName()+")=" + properties + "]";
    }
}

另请参阅我在这个问题的答案:杰克逊JsonTypeInfo.As.EXTERNAL_PROPERTY没有按预期工作


答案 2