Как можно полиморфная десериализация Json String с использованием Java и библиотеки Jackson?

У меня есть некоторые classы A, B, C, которые они наследуют от classа BaseClass.

У меня есть String json, который содержит json-представление A, B, C или BaseClass.

Я хочу иметь некоторый способ десериализации этой строки в BaseClass (полиморфная десериализация). Что-то вроде этого

BaseClass base = ObjectMapper.readValue(jsonString, BaseClass.class); 

jsonString может быть представлением Json String любого из A, B, C или BaseClass.

Неясно, с какими проблемами сталкивается оригинальный плакат. Я предполагаю, что это одна из двух вещей:

  1. Проблемы десериализации с несвязанными элементами JSON, поскольку JSON содержит элементы, для которых в Java не существует привязки; или

  2. Хотите реализовать полиморфную десерилизацию.

Вот решение первой проблемы.

 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;} } 

Если вместо этого целью является десериализация типа подclassа без элемента JSON, специально предназначенного для указания того, какой тип подclassа, то это также возможно, если что-то в JSON можно использовать для определения того, какой тип подclassа должен быть , Я привел пример такого подхода в http://programmerbruce.blogspot.com/2011/05/deserialize-json-with-jackson-into.html .

Вы посмотрели библиотеку Google Gson? Я думаю, что он делает то, что вы ищете.

http://code.google.com/p/google-gson/

  • Сохранение / загрузка данных в Unity
  • Как изменить имена свойств при сериализации с помощью Json.net?
  • В чем разница между привязкой лямбды и метода на уровне выполнения?
  • GSON десериализует значение ключа для пользовательского объекта
  • Рекомендации по сериализации объектов в пользовательский строковый формат для использования в выходном файле
  • Есть ли у .NET 4 встроенный сериализатор / десериализатор JSON?
  • ТипNameHandling предостережение в Newtonsoft Json
  • Как добавить тип в белый список политики сериализации GWT?
  • Задача не сериализуема: java.io.NotSerializableException при вызове функции закрытие только для classов не объектов
  • jackson - Как обрабатывать (десериализовать) вложенный JSON?
  • Сериализация OpenCV Mat_
  • Давайте будем гением компьютера.