Я пытаюсь десериализовать JSON определенной структуры в классы Java с помощью Джексона. У меня есть несколько таких классов:
class A {
private int number1;
private List<X> list1;
private int number2;
}
class X {
private String field1;
private double value1;
}
class B {
private String name2;
private List<Y> list2;
}
class Y {
private String field2;
}
И я получаю JSON из внешней системы, как показано ниже:
{
"number1": 1,
"list1": {
"elements": [{
"field1": "Field 1 value 1",
"value1": 2.2
}, {
"field1": "Field 1 value 2"
}]
},
"number2": 2,
}
{
"name2": "Name 2",
"list2": {
"elements": [{
"field2": "Field 2 value 1"
}]
}
}
Все, что я хочу, это написать собственный десериализатор, который мог бы избавиться от этого уровня элементы общим способом (я имею в виду иметь один десериализатор для всех классов). Есть ли простой способ расширить StdDeserializer для этого или мне нужно написать совершенно новый десериализатор с моим собственным алгоритмом?
Я не понимаю, что это меняет? Это просто техническая проблема.
мы можем сделать это простым способом, отличным от пользовательского десериализатора
В общем, эти JSON могут иметь любую структуру, и я обновил пример выше. Одно можно сказать наверняка, что коллекции будут отправляться так: "имя_коллекции": { "элементы": [{ ... }] } и я пытаюсь избавиться от этого уровня элементы.
Связано: stackoverflow.com/questions/11747370/…
Спасибо за ссылку, но это не помогает мне в создании универсального решения, которое позволяет иметь списки на каждом уровне JSON.




Вы можете взглянуть на этот вопрос: Джексон - десериализовать внутренний список объектов в список одного более высокого уровня, который очень похож. Я реализовал там собственный десериализатор, который можно использовать для разных типов с внутренним списком. Ваш пример POJO может выглядеть так:
class A {
private int number1;
@JsonDeserialize(using = InnerListDeserializer.class)
private List<X> list1;
private int number2;
// getters, setters
}
РЕДАКТИРОВАТЬ
Если вы не хотите использовать какую-либо аннотацию или пользовательскую десериализацию, вам необходимо создать структуру POJO, которая соответствует заданному JSON. Вам нужно создать средний POJO:
class ListWrapper<T> {
private List<T> elements;
// getter, setter, toString, etc
}
Теперь вам нужно обновить классы A и B следующим образом:
class A {
private int number1;
private ListWrapper<X> list1;
private int number2;
// getters, setters, toString
}
и
class B {
private String name2;
private ListWrapper<Y> list2;
// getters, setters, toString
}
Извините за поздний ответ. Я хочу решить эту проблему более широко и без аннотаций Джексона (я хочу выставить чистые классы POJO без метаданных). Могу предположить, что внешняя система всегда обслуживает коллекции, как в примере JSON (с уровнем элементов).
Цитата из вашего вопроса: «Все, что я хочу, это написать собственный десериализатор, который мог бы избавиться от этого уровня элементов в общем виде». Итак, теперь вы не хотите реализовывать собственный десериализатор и создавать набор классов POJO, которые подходят для данного JSON?
Это небольшое недоразумение. Я хочу зарегистрировать глобальный десериализатор в Джексоне, чтобы десериализовать все списки (с уровнем элементов) в общем виде, что для меня означает: без дополнительных аннотаций к модели.
Я понимаю это сейчас. Это немного сложная проблема. Как вы можете проверить, мой пользовательский десериализатор из другого вопроса использует десериализатор Jsckson по умолчанию для списка. Непростая задача правильно расширить его и десериализовать список с помощью специального десериализатора. Вам нужно знать тип элемента и прочитать все используемые там аннотации. Вы можете попробовать расширить com.fasterxml.jackson.databind.deser.std.CollectionDeserializer, но намного проще использовать мой InnerListDeserializer. Если вы не можете изменить классы, используйте функцию MixIn. Если вы думаете, что мой ответ вам не поможет, я могу удалить его.
Вы хоть представляете, сколько псевдонимов существует для
name1?