繁体   English   中英

Json 和 Java - 循环参考

[英]Json and Java - Circular Reference

我对循环引用有疑问。

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

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

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

控制器方法头是:

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

我没有做任何明确的事情来转换为 Json,我是这个新手,我认为 jackson 自动解决了这个问题。

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

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

您可以在此处查看示例。

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

更新

这是一个很好的博客文章在这里是进入你能处理杰克逊双向关系的各种方式的细节。 它描述了使用@JsonIgnore@JsonManagedReference@JsonBackReference@JsonIdentityInfo@JsonView和自定义序列化程序的解决方案。 这是您可以使用的各种技术的非常全面的文章。

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM