Дезериализация вложенного объекта Джексона в собственность - PullRequest
3 голосов
/ 04 ноября 2011

Предположим, у меня есть объект json, который выглядит следующим образом:

  {
    id: 1,
    name: "john doe"
    spouse: 2
  }

и класс, для которого я хочу десериализовать его:

class Person{

  private Long id;
  private String name;

  private Person spouse;

  //getters/setters
}

Можно ли сказать Джексону расширить свойство spouse: 2 в новый Person POJO с id=2 при десериализации JSON?

Я столкнулся с этой проблемой в результате десериализации JSON в постоянные сущности и хотел бы иметь возможность легко сохранять отношения между этими сущностями.

Ответы [ 2 ]

3 голосов
/ 04 ноября 2011

Помимо полной десериализации, существует более простой способ: определить POJO с помощью одного конструктора int-arg, например:

class Person {
   int id;
   public Person(int id) {
     this.id = id;
   }
}

Это на самом деле работает, так как Джексон будет пытаться найти ограниченное количество специальных конструкторов (открытых конструкторов с одним аргументом, которые принимают String, int, long, double или boolean).

При желании вы также можете обозначить их с помощью @JsonCreator - и если конструктор не является общедоступным, вы должны сделать это, чтобы сделать его доступным для обнаружения. Но для публичных ctor это не нужно.

2 голосов
/ 04 ноября 2011

Конечно, Джексон не может вывести полностью заполненный объект Person, представляющий супруга из числа 2.Скорее всего, вам потребуется зарегистрировать пользовательский десериализатор, который проверяет, является ли ввод целым числом, и, если это так, ищет супруга, где бы он ни хранился.Я не делал такого рода вещей для классов, которые содержат ссылки на себя (например, ваш Person содержит Person), поэтому я могу дать вам только приблизительное руководство.

Я считаю, что это может работать только с Джексономверсия 1.9 или выше.По сути, вы можете зарегистрировать модуль в сопоставителе объектов, который говорит Джексону использовать собственный десериализатор.

SimpleModule module = new SimpleModule("PeopleModule", new Version(1, 1, 0, null);
module.addDeserializer(Person.class, new JacksonPersonDeserializer());

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);

В качестве альтернативы для самого класса Person вы можете сделать что-то вроде:

class Person {

  @JsonDeserialize(using=JacksonPersonDeserializer.class)
  Person spouse;
}

Это работает до 1.9, но загрязняет ваш объект.В любом случае вам нужно написать собственный десериализатор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...