目前尚不清楚原始海报遇到了什么问题。我猜这是两件事之一:
未绑定的JSON元素存在反序列化问题,因为JSON包含Java中没有任何内容可以绑定的元素;或
想要实现多态反序列化。
这是第一个问题的解决方案。
import static org.codehaus.jackson.map.DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES;
import org.codehaus.jackson.map.ObjectMapper;
public class Foo
{
public static void main(String[] args) throws Exception
{
BaseClass base = new BaseClass();
A a = new A();
B b = new B();
C c = new C();
ObjectMapper mapper = new ObjectMapper();
String baseJson = mapper.writeValueAsString(base);
System.out.println(baseJson); // {"baseName":"base name"}
String aJson = mapper.writeValueAsString(a);
System.out.println(aJson); // {"baseName":"base name","aName":"a name"}
String bJson = mapper.writeValueAsString(b);
System.out.println(bJson); // {"baseName":"base name","bName":"b name"}
String cJson = mapper.writeValueAsString(c);
System.out.println(cJson); // {"baseName":"base name","cName":"c name"}
BaseClass baseCopy = mapper.readValue(baseJson, BaseClass.class);
System.out.println(baseCopy); // baseName: base name
// BaseClass aCopy = mapper.readValue(aJson, BaseClass.class);
// throws UnrecognizedPropertyException:
// Unrecognized field "aName", not marked as ignorable
// because the JSON contains elements for which no Java field
// to bind to was provided.
// Need to let Jackson know that not all JSON elements must be bound.
// To resolve this, the class can be annotated with
// @JsonIgnoreProperties(ignoreUnknown=true) or the ObjectMapper can be
// directly configured to not FAIL_ON_UNKNOWN_PROPERTIES
mapper = new ObjectMapper();
mapper.configure(FAIL_ON_UNKNOWN_PROPERTIES, false);
BaseClass aCopy = mapper.readValue(aJson, BaseClass.class);
System.out.println(aCopy); // baseName: base name
BaseClass bCopy = mapper.readValue(bJson, BaseClass.class);
System.out.println(bCopy); // baseName: base name
BaseClass cCopy = mapper.readValue(cJson, BaseClass.class);
System.out.println(cCopy); // baseName: base name
}
}
class BaseClass
{
public String baseName = "base name";
@Override public String toString() {return "baseName: " + baseName;}
}
class A extends BaseClass
{
public String aName = "a name";
@Override public String toString() {return super.toString() + ", aName: " + aName;}
}
class B extends BaseClass
{
public String bName = "b name";
@Override public String toString() {return super.toString() + ", bName: " + bName;}
}
class C extends BaseClass
{
public String cName = "c name";
@Override public String toString() {return super.toString() + ", cName: " + cName;}
}
这是第二个问题的解决方案。
import org.codehaus.jackson.annotate.JsonSubTypes;
import org.codehaus.jackson.annotate.JsonSubTypes.Type;
import org.codehaus.jackson.annotate.JsonTypeInfo;
import org.codehaus.jackson.map.ObjectMapper;
public class Foo
{
public static void main(String[] args) throws Exception
{
BaseClass base = new BaseClass();
A a = new A();
B b = new B();
C c = new C();
ObjectMapper mapper = new ObjectMapper();
String baseJson = mapper.writeValueAsString(base);
System.out.println(baseJson); // {"type":"BaseClass","baseName":"base name"}
String aJson = mapper.writeValueAsString(a);
System.out.println(aJson); // {"type":"a","baseName":"base name","aName":"a name"}
String bJson = mapper.writeValueAsString(b);
System.out.println(bJson); // {"type":"b","baseName":"base name","bName":"b name"}
String cJson = mapper.writeValueAsString(c);
System.out.println(cJson); // {"type":"c","baseName":"base name","cName":"c name"}
BaseClass baseCopy = mapper.readValue(baseJson, BaseClass.class);
System.out.println(baseCopy); // baseName: base name
BaseClass aCopy = mapper.readValue(aJson, BaseClass.class);
System.out.println(aCopy); // baseName: base name, aName: a name
BaseClass bCopy = mapper.readValue(bJson, BaseClass.class);
System.out.println(bCopy); // baseName: base name, bName: b name
BaseClass cCopy = mapper.readValue(cJson, BaseClass.class);
System.out.println(cCopy); // baseName: base name, cName: c name
}
}
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type")
@JsonSubTypes({
@Type(value = A.class, name = "a"),
@Type(value = B.class, name = "b"),
@Type(value = C.class, name = "c") })
class BaseClass
{
public String baseName = "base name";
@Override public String toString() {return "baseName: " + baseName;}
}
class A extends BaseClass
{
public String aName = "a name";
@Override public String toString() {return super.toString() + ", aName: " + aName;}
}
class B extends BaseClass
{
public String bName = "b name";
@Override public String toString() {return super.toString() + ", bName: " + bName;}
}
class C extends BaseClass
{
public String cName = "c name";
@Override public String toString() {return super.toString() + ", cName: " + cName;}
}
相反,如果目标是反序列化为子类类型,而没有专门用于指示子类类型的JSON元素,那么这也是可能的,只要JSON中的某些内容可以用来决定子类类型应该是什么。我在 http://programmerbruce.blogspot.com/2011/05/deserialize-json-with-jackson-into.html 上发布了这种方法的一个例子。