Json和Java - 循环参考

时间:2013-06-30 19:00:06

标签: java json jackson circular-reference

我正在使用并发布循环参考。

我有Rest Webservices将对象返回到前端,问题是当我尝试返回具有多个引用的对象时,结果我得到无限响应,生成

java.lang.IllegalStateException: 
    Cannot call sendError() after the response has been committed

对象是由Hibernate代码生成自动生成的,我需要在后端使用循环引用,我只需要在使用Jackson将信息发送到前端之前将其删除。

控制器方法标题是:

@RequestMapping(value="/list", method=RequestMethod.POST)
public @ResponseBody eventResponse list(@RequestBody String sessionID) {

我没有做任何明确的转换为Json,我是一个新手,我认为杰克逊自动解决了这个问题。

3 个答案:

答案 0 :(得分:32)

有两种方法可以解决这个问题。如果您必须将您的实体暴露给外界,我建议在导致循环引用的属性上添加@JsonIgnore。这将告诉杰克逊不要序列化该财产。

另一种方法是使用Jackson提供的双向功能。您可以使用@JsonManagedReference@JsonBackReference@JsonManagedReference是属性的“前向”部分,它将正常序列化。 @JsonBackReference是参考文献的“后退”部分;它不会被序列化,但会在“转发”类型被反序列化时重建。

您可以查看示例here

这解决了您的评论:我认为在这种情况下您可能想要做的是使用外部世界可见的DTO。我喜欢这种方法,因为我不想将我的实体暴露给外面。这意味着杰克逊的注释将在DTO而不是在整体上。您需要某种将实体转换为DTO的映射器或转换器。现在,当您对实体进行更改时,除非您修改映射器/转换器,否则它们不会传播到DTO。我认为这没关系,因为当您对实体进行更改时,您可以决定是否要公开更改。

<强>更新

有一篇很好的博客文章here详细介绍了处理杰克逊双向关系的各种方法。它描述了使用@JsonIgnore@JsonManagedReference@JsonBackReference@JsonIdentityInfo@JsonView以及自定义序列化程序的解决方案。这是您可以使用的各种技术的全面综述。

答案 1 :(得分:7)

单个注释@JsonIdentityInfo解决了问题。它也处理循环引用。Reference

答案 2 :(得分:0)

@JsonbTransient解决了我处理循环引用的问题:

@JsonbTransient // javax.json.bind.annotation.JsonbTransient
@ManyToOne
@JoinColumn(name = "userId", referencedColumnName = "id", nullable = false)
public AContainedEntity getAContainedEntity() {
       return aContainedEntity;
}