Java: Jackson polymorphic JSON deserialization of an object with an interface property?(Java:具有接口属性的对象的杰克逊多态 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 有两个属性:type 和 properties.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 的接口,我有几个实现它的类(例如DocumentAssetProperties、ImageAssetProperties).这个想法是图像文件具有与文档文件等不同的属性(高度、宽度).
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,这需要一些谷歌搜索.这是一个更新的 Gist 和工作代码:
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:具有接口属性的对象的杰克逊多态 JSON 反序列化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Java:具有接口属性的对象的杰克逊多态 JSON 反序列化?
				
        
 
            
        - Eclipse 的最佳 XML 编辑器 2022-01-01
 - java.lang.IllegalStateException:Bean 名称“类别"的 BindingResult 和普通目标对象都不能用作请求属性 2022-01-01
 - 如何指定 CORS 的响应标头? 2022-01-01
 - 在 Java 中,如何将 String 转换为 char 或将 char 转换 2022-01-01
 - 如何使 JFrame 背景和 JPanel 透明且仅显示图像 2022-01-01
 - 转换 ldap 日期 2022-01-01
 - GC_FOR_ALLOC 是否更“严重"?在调查内存使用情况时? 2022-01-01
 - 将 Java Swing 桌面应用程序国际化的最佳实践是什么? 2022-01-01
 - 获取数字的最后一位 2022-01-01
 - 未找到/usr/local/lib 中的库 2022-01-01
 
						
						
						
						
						
				
				
				
				