【问题标题】:How do I prevent an infinite loop when serializing a 3-node reference in Java into JSON?将Java中的3节点引用序列化为JSON时如何防止无限循环?
【发布时间】:2013-07-10 21:15:46
【问题描述】:

在我的 Spring MVC 应用程序中,我有三个类 - Content、Category 和 Document - 它们都是相互关联的,并且必须序列化为 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)”,然后是引用链的跟踪。

【问题讨论】:

    标签: java json serialization jackson


    【解决方案1】:

    也许看看@JsonIdentityInfo注解,它可以用来处理循环依赖(this entry提到它)?它不适用于Collections(唉),但适用于集合、数组和映射中包含的 POJO。

    【讨论】:

    • 由于关系的性质,这会变得有点过于复杂。如果有更多时间,我可能会进一步测试这个理论,但业务需求促使我建立一个新的资源模型。
    • 嗯?为您的 3 个类添加注释太复杂?如果做得好,它并不复杂,完全是声明性的。
    【解决方案2】:

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

    使用这种新机制,您可以使用 @JsonIdentityInfo 注释来注释所有三个对象(ContentDocumentCategory),然后 Jackson 应该能够正确地序列化(和反序列化)它们。

    简单代码示例:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 不能@JsonIgnore 任何字段,因为这些引用在其他视图中是必需的,例如我在另一个视图中使用 document.contents。
      【解决方案4】:

      您尝试过转换器吗?

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

      【讨论】:

        猜你喜欢
        • 2011-01-19
        • 1970-01-01
        • 1970-01-01
        • 2013-08-25
        • 1970-01-01
        • 2016-09-13
        • 2012-10-18
        • 1970-01-01
        相关资源
        最近更新 更多