![](/img/trans.png)
[英]How can I deserialize a Json String to get polymorphic result using Java and Jackson Library?
[英]How can I polymorphic deserialization Json String using Java and Jackson Library?
我有一些類A,B,C它們都繼承自BaseClass類。
我有一個String json,它包含A,B,C或BaseClass的json表示。
我想有一些方法將此String反序列化為BaseClass(多態反序列化)。 像這樣的東西
BaseClass base = ObjectMapper.readValue(jsonString, BaseClass.class);
jsonString
可以是A,B,C或BaseClass中的任何一個的Json String表示。
目前尚不清楚原始海報有什么問題。 我猜這是兩件事之一:
未綁定的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上發布了這種方法的示例。
你看過谷歌的Gson圖書館嗎? 我認為它可以滿足您的需求。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.