Я пишу сериализатор для сериализации POJO к JSON, но всунутой проблеме циклической ссылки. В в спящем режиме двунаправленное one-many отношение, порождают ссылочного ребенка и дочерние ссылки назад для порождения, и здесь мой сериализатор перестает работать. (см. пример кода ниже),
Как повредить этот цикл? Мы можем получить дерево владельца объекта видеть, существует ли сам объект где-нибудь в его собственной иерархии владельца? Какой-либо другой способ найти, будет ли ссылка круговой? или какая-либо другая идея разрешить эту проблему?
Можно ли даже представить двунаправленную связь в JSON? Некоторые форматы данных не подходят для некоторых типов моделирования данных.
Один из методов работы с циклами при обходе графов объектов - отслеживать, какие объекты вы уже видели (с помощью сравнения идентичностей), чтобы не допустить прохождения бесконечного цикла.
Я полагаюсь на 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 класс
Jackson В версии 1.6 (выпущенной в сентябре 2010 года) есть специальная поддержка на основе аннотаций для обработки такой связи родитель/ребенок, см. http://wiki.fasterxml.com/JacksonFeatureBiDirReferences. (Wayback Snapshot)
Конечно, вы можете исключить сериализацию родительской ссылки уже сейчас, используя большинство пакетов обработки JSON (jackson, gson и flex-json, по крайней мере, поддерживают это), но настоящий фокус в том, как десериализовать ее обратно (воссоздать родительскую ссылку), а не только в обработке сериализации. Хотя, похоже, что пока для вас подойдет только исключение.
EDIT (апрель 2012): Jackson 2.0 теперь поддерживает истинные идентификационные ссылки (Wayback Snapshot), так что вы можете решить эту проблему и таким способом.