Как решить циклическую ссылку в json сериализаторе, вызванном, в спящем режиме двунаправленное отображение?

Я пишу сериализатор для сериализации POJO к JSON, но всунутой проблеме циклической ссылки. В в спящем режиме двунаправленное one-many отношение, порождают ссылочного ребенка и дочерние ссылки назад для порождения, и здесь мой сериализатор перестает работать. (см. пример кода ниже),
Как повредить этот цикл? Мы можем получить дерево владельца объекта видеть, существует ли сам объект где-нибудь в его собственной иерархии владельца? Какой-либо другой способ найти, будет ли ссылка круговой? или какая-либо другая идея разрешить эту проблему?

74
задан WSK 27 July 2010 в 03:11
поделиться

3 ответа

Можно ли даже представить двунаправленную связь в JSON? Некоторые форматы данных не подходят для некоторых типов моделирования данных.

Один из методов работы с циклами при обходе графов объектов - отслеживать, какие объекты вы уже видели (с помощью сравнения идентичностей), чтобы не допустить прохождения бесконечного цикла.

10
ответ дан 24 November 2019 в 12:03
поделиться

Я полагаюсь на Google JSON Чтобы решить эту проблему с помощью функции

Исключение полей из сериализации и десериализации

Предположим, что между классами A и B существует двунаправленная связь

public class A implements Serializable {

    private B b;

}

И B

public class B implements Serializable {

    private A a;

}

Теперь используйте GsonBuilder, чтобы получить пользовательский объект Gson следующим образом (уведомление setExclusionStrategies метод)

Gson gson = new GsonBuilder()
    .setExclusionStrategies(new ExclusionStrategy() {

        public boolean shouldSkipClass(Class<?> clazz) {
            return (clazz == B.class);
        }

        /**
          * Custom field exclusion goes here
          */
        public boolean shouldSkipField(FieldAttributes f) {
            return false;
        }

     })
    /**
      * Use serializeNulls method if you want To serialize null values 
      * By default, Gson does not serialize null values
      */
    .serializeNulls()
    .create();

Теперь наша циклическая ссылка

A a = new A();
B b = new B();

a.setB(b);
b.setA(a);

String json = gson.toJson(a);
System.out.println(json);

Взгляните на GsonBuilder класс

45
ответ дан 24 November 2019 в 12:03
поделиться

Jackson В версии 1.6 (выпущенной в сентябре 2010 года) есть специальная поддержка на основе аннотаций для обработки такой связи родитель/ребенок, см. http://wiki.fasterxml.com/JacksonFeatureBiDirReferences. (Wayback Snapshot)

Конечно, вы можете исключить сериализацию родительской ссылки уже сейчас, используя большинство пакетов обработки JSON (jackson, gson и flex-json, по крайней мере, поддерживают это), но настоящий фокус в том, как десериализовать ее обратно (воссоздать родительскую ссылку), а не только в обработке сериализации. Хотя, похоже, что пока для вас подойдет только исключение.

EDIT (апрель 2012): Jackson 2.0 теперь поддерживает истинные идентификационные ссылки (Wayback Snapshot), так что вы можете решить эту проблему и таким способом.

33
ответ дан 24 November 2019 в 12:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: