本文介绍了Java:Jackson 多态 JSON 反序列化具有接口属性的对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using Jackson's ObjectMapper to deserialize a JSON representation of an object that contains an interface as one of its properties. A simplified version of the code can be seen here:

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

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

Basically, I have a class Asset with two properties: type and properties. The JSON model looks like this:

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

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

The properties property is defined as an interface called AssetProperties, and I have several classes that implement it (e.g. DocumentAssetProperties, ImageAssetProperties). The idea is that image files have different properties (height, width) than document files, etc.

我已经完成了本文中的示例,阅读关于 SO 及其他方面的文档和问题,并在 @JsonTypeInfo 注释参数中尝试不同的配置,但一直无法破解这个问题.任何帮助将不胜感激.

I've worked off of the examples in this article, read through docs and questions here on SO and beyond, and experimented with different configurations in the @JsonTypeInfo annotation parameters, but haven't been able to crack this nut. Any help would be greatly appreciated.

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

Most recently, the exception I'm getting is this:

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,我能够解决这个问题.我还可以使用 Enum 作为类型 id,这需要用一些谷歌搜索.这是带有工作代码的更新要点:

With many thanks to @Michał Ziober, I was able to resolve this issue. I was also able to use an Enum as a type id, which took a bit of Googling. Here is an updated Gist with working code:

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

推荐答案

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

You should use JsonTypeInfo.As.EXTERNAL_PROPERTY instead of JsonTypeInfo.As.PROPERTY. In this scenario your Asset class should look like this:

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

另见我在这个问题中的回答:JacksonJsonTypeInfo.As.EXTERNAL_PROPERTY 未按预期工作.

See also my answer in this question: Jackson JsonTypeInfo.As.EXTERNAL_PROPERTY doesn't work as expected.

这篇关于Java:Jackson 多态 JSON 反序列化具有接口属性的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-03 03:37