I'm trying to use Jakson to deserialize a nested polymorphic type. Meaning my top level type referes to another polymorphic type that finally is extended by class that's not abstract. This does not work and it throws an exception.
Here is a reduced example of what I'm trying to do.
package com.adfin;
import junit.framework.TestCase;
import org.codehaus.jackson.annotate.JsonSubTypes;
import org.codehaus.jackson.annotate.JsonTypeInfo;
import org.codehaus.jackson.map.ObjectMapper;
import java.io.IOException;
public class JaksonDouble extends TestCase {
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "name"
)
@JsonSubTypes({
@JsonSubTypes.Type(value = SecondLevel.class, name = "SECOND")
})
public static abstract class FirstLevel {
public abstract String getTestValue();
}
@JsonTypeInfo(
use = JsonTypeInfo.Id.CLASS,
include = JsonTypeInfo.As.PROPERTY,
property = "@class"
)
public static abstract class SecondLevel extends FirstLevel {
}
public static class FinalLevel extends SecondLevel {
String test;
@Override public String getTestValue() { return test; }
}
public void testDoubleAbstract() throws IOException {
String testStr = "{ "name": "SECOND", "@class": "com.adfin.JasksonDouble.FinalLevel", "test": "foo"}";
ObjectMapper mapper = new ObjectMapper();
FirstLevel result = mapper.readValue(testStr, FirstLevel.class);
}
}
I get the standard exception about abstract types.
org.codehaus.jackson.map.JsonMappingException: Can not construct instance of com.adfin.JaksonDouble$SecondLevel, problem: abstract types can only be instantiated with additional type information at [Source: java.io.StringReader@f2a55aa; line: 1, column: 19]
Let me explain my use case. I have a Json document describing a workflow on data. I have an abstract type at "level one" describing an operation on a single value. I derive a bunch of classes that are not abstract that implement common operations (I annotate all of them with @JsonSubTypes).
I have one special @JsonSubTypes that is called "CUSTOM". This is another abstract class that represents custom operations that someone else wrote (outside of the normal jar) and they can specify a fully qualified class name using the "@class" property. It looks like the Jakson parser never reads the @JsonTypeInfo annotation on the second lavel class.
How can I make this work. Or at least how can I make this use case work.
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…