Json 和 Java - 循环参考 [英] Json and Java - Circular Reference

查看:23
本文介绍了Json 和 Java - 循环参考的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对循环引用有疑问.

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

I have Rest Webservices which returns objects to the front end, the issue is when I try to return objects that have several references so as the result I get an infinite response, which generate

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

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

The objects are generated automatically by Hibernate Code Generation and I need to have the circular reference in the backend, I've just need to remove it before send the information to the frontend using Jackson.

控制器方法头是:

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

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

I'm not doing anything explicite to convert to Json, I'm a newby with this and I think that jackson resolved this automatically.

推荐答案

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

There are two ways you can go about this. If you must expose your entity to the outside world, I recommend adding @JsonIgnore on the property that is causing the circular reference. This will tell Jackson not to serialize that property.

另一种方式是使用Jackson 提供的双向特性.您可以使用 @JsonManagedReference@JsonBackReference.@JsonManagedReference 是属性的转发"部分,它将正常序列化.@JsonBackReference 是引用的后退"部分;不会被序列化,但会在forward"类型反序列化时重构.

Another way is to use the bidirectional features provided by Jackson. You can either use @JsonManagedReference or @JsonBackReference. @JsonManagedReference is the "forward" part of the property and it will get serialized normally. @JsonBackReference is the "back" part of the reference; it will not be serialized, but will be reconstructed when the "forward" type is deserialized.

您可以在此处查看示例.

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

This addresses your comment: I think what you might want to do in this case is use a DTO that is visible to the outside world. I like this approach because I don't want to expose my entities to the outside. This means that the Jackson annotations would be on the DTO and not on the enity. You would need some sort of mapper or converter that converts the entity to the DTO. Now when you make changes to your entity, they won't get propagated to the DTO unless you modify your mapper/converter. I think this is ok, because when you make a change to your entity you can decide if you want that change to be exposed or not.

更新

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

There is a good blog post here that goes into detail about the various ways you can handle bidirectional relationships in Jackson. It describes solutions that use @JsonIgnore, @JsonManagedReference and @JsonBackReference, @JsonIdentityInfo, @JsonView and a custom serializer as well. It's a pretty comprehensive writeup of the various techniques that you can use.

这篇关于Json 和 Java - 循环参考的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆