Json和Java – 循环参考

我有并且发布了循环参考。

我有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,我是一个新手,我认为jackson自动解决了这个问题。

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

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

你可以在这里看看这些例子。

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

UPDATE

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

单个注释@JsonIdentityInfo可以解决问题。 它也处理循环引用。 参考