我正在使用 Jackson 的 ObjectMapper
反序列化包含接口(interface)作为其属性之一的对象的 JSON 表示。代码的简化版本可以在这里看到:
https://gist.github.com/sscovil/8735923
基本上,我有一个类 Asset
,它有两个属性:type
和 properties
。 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:
最佳答案
您应该使用 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/