在将Java中的3节点引用序列化为JSON时,如何防止无限循环?

时间:2013-07-10 21:15:47

标签: java json serialization jackson

在我的Spring MVC应用程序中,我有三个类 - 内容,类别和文档 - 它们都是相互关联的,必须序列化为JSON,但这样做会导致无限循环。这种关系是这样的:

Content -> List<Category> -> List<Document> -> List<Content> -> (etc.)

其中Category是Content等的属性。我正在尝试序列化它以便引用在List结束(以便content.categories.documents暴露给视图),但没有找到任何方法去做它。使用Jackson的@JsonManagedReference和@JsonBackReference进行注释将无法正常工作,因为其中一些字段已经注释为其他关系。除了可能构建特定于相关视图的模型之外,不确定如何解决此问题。

编辑:如果这有帮助,我得到的错误是“org.springframework.http.converter.HttpMessageNotWritableException:无法写入JSON:无限递归(StackOverflowError)”,后跟跟踪链的跟踪。

4 个答案:

答案 0 :(得分:1)

或许可以查看@JsonIdentityInfo注释,它可以用来处理循环依赖(this entry提到它)?它不适用于Collection(唉),但适用于集合,数组和地图中包含的POJO。

答案 1 :(得分:1)

@JsonManagedReference@JsonBackReference在他们可以处理的周期类型方面相当有限。特别是它们只能用于表示相当静态的父子类型关系。实质上,它们只能用于处理严格的层次结构。但是在大量项目中,对象关系实际上由图形表示,前面提到的两个注释根本无法处理。杰克逊的设计师意识到了这一点,在图书馆的2.0版本中他们引入了new mechanism for handling object identity

使用这种新机制,您可以使用Content注释对所有三个对象(DocumentCategory@JsonIdentityInfo)进行注释,然后杰克逊应该能够正确地序列化(和反序列化)。

简单的代码示例:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
    property = "someUniquePropertyOfYourClass")
public class Context {
    // fields, constructors, getters/setters
}

答案 2 :(得分:0)

您是否尝试过使用@JsonIgnore?当我在Spring MVC中使用Hibernate时,它在我的情况下工作得更好。

答案 3 :(得分:0)

你试过转换器吗?

使用其他两个类的转换器单独序列化每个类。例如,在序列化内容时,请为类别和文档编写转换器。转换可以是类别和文档的标识符。在反序列化时,首先获取对象并记住它们之间的关系。然后使用标识符重建他们的关系。