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

标签 java json jackson deserialization polymorphism

我正在使用 Jackson 的 ObjectMapper 反序列化包含接口(interface)作为其属性之一的对象的 JSON 表示。代码的简化版本可以在这里看到:

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

基本上,我有一个类 Asset,它有两个属性:typeproperties。 JSON 模型如下所示:

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

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

我已经完成了 this article 中的示例,阅读有关 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,这需要一些谷歌搜索。这是带有工作代码的更新 Gist:

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

最佳答案

您应该使用 JsonTypeInfo.As.EXTERNAL_PROPERTY 而不是 JsonTypeInfo.As.PROPERTY。在这种情况下,您的 Asset 类应该如下所示:

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 + "]";
    }
}

另请参阅我在这个问题中的回答:Jackson JsonTypeInfo.As.EXTERNAL_PROPERTY doesn't work as expected .

关于Java:具有接口(interface)属性的对象的 Jackson 多态 JSON 反序列化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21485923/

相关文章:

javascript - Angular .js : How to bind "change" event to service

java - 有没有办法默认@JsonIgnore,以及允许序列化的标签

php - 循环遍历 Laravel 集合并使用 Redis 存储到 key

java - 如何通过 "Global default typing"在 Jackson 中启用 "jackson2ObjectMapperBuilder"

java - 构造正则表达式模式以匹配句子

java - Spigot/Bukkit - 播放自己的声音/音乐 - Java

java - 什么是NullPointerException,我该如何解决?

java - google protocol buffers如何在protocol buffers proto文件中定义List<Object>

json - 使用 Jackson JSON View 而不注释原始 bean 类

java - 使用jackson将json数据映射到java中的两个不同实体