Страницы

Поиск по вопросам

среда, 13 марта 2019 г.

Бесконечное извлечение из двух set- ов

Есть 2 pojo класса:
public class Component { private String ID; private Set environmentSet;
public class Environment { private String host; private String name; private Set components;
И контейнер для второго:
public class EnvironmentContainer { private List allEnvironments;
Мне по данному пути нужно вернуть лист из контейнера
@RequestMapping("/environments") @ResponseBody public List getAllEnvironments() { return environmentcontainer.getAllEnvironments(); }
При выполнении возникает ошибка, скорее всего из за взаимосвязи между pojo, построенной на set:
java.lang.IllegalStateException: Cannot call sendError() after the response has been committed at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:466)
Слышал в спринге есть аннотация, которая обрубает бесконечное извлечение, или есть другие пути как это исправить?


Ответ

Нижеизложенное справедливо если вы используете Jackson для сериализации ваших бинов.
В Jackson есть аннотации, позволяющие управлять сериализацией бинов, связанных циклическими ссылками. Это @JsonManagedReference и @JsonBackReference. Первой помечается поле или геттер основного класса (с которого начинается сериализация) со ссылками на зависимые объекты, второй - поле или геттер зависимого класса со ссылкой на основной:
public class Environment { @JsonManagedReference private Set components; }
public class Component { @JsonBackReference private Set environmentSet; }
Теперь Jackson не уйдёт в бесконечную рекурсию при сериализации.
Другая аннотация, которая может помочь - @JsonIgnore. Поля, помеченные такой аннотацией, не включаются в сериализованный объект. Если объекты класса Component никогда не будут сериализовываться отдельно от объектов Environment, то можно пометить поле environmentSet аннотацией @JsonIgnore, эффект будет аналогичный.
Ещё один вариант - @JsonIdentityInfo. Этой аннотацией помечается весь класс. С её помощью можно подсказать Jackson'у, как определить уникальный ключ объекта (например, по полю ID):
@JsonIdentityInfo( generator = ObjectIdGenerators.PropertyGenerator.class, property = "ID") public class Environment { ... }
Встретив при сериализации объект с ключом, который он уже обрабатывал, Jackson подставит вместо него его ключ.
Также есть возможность управлять сериализацией циклических ссылок через @JsonView (подробнее об этом и других способах читайте в этой статье), но это требует регистрации в Spring'е кастомного сериализатора.

Комментариев нет:

Отправить комментарий