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
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"
}
}
The properties
property is defined as an interface called AssetProperties
, and I have several classes that implement it (eg DocumentAssetProperties
, ImageAssetProperties
). The idea is that image files have different properties (height, width) than document files, etc.
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]
Thanks in advance!
SOLUTION:
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:
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 + "]";
}
}
See also my answer in this question: Jackson JsonTypeInfo.As.EXTERNAL_PROPERTY doesn't work as expected .
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.