杰克逊深嵌套物体

时间:2013-01-10 19:15:37

标签: json spring rest jackson

我有以下java JPA对象,它们在我的spring rest controller方法中被转换为json,它们是

class User{
    @JsonManagedReference
    @OneToMany
    private Portfolio portfolio;
    .....
}

class Portfolio {
     @JsonBackReference
     @ManyToOne
 private User user;

    @JsonManagedReference
     private List<Order> orders;
     .....
}

class Order {
     @JsonBackReference
 private Portfolio portfolio;

     private User user;
}

在我的应用程序中,我需要2项服务:

  
      
  1. 登录:   返回User对象,使用Portfolio和Orders List对象,我不需要Order.user对象。

  2.   
  3. GetOrders:   返回一个Orders列表,我需要Order.user对象。

  4.   

Order.user与父用户对象不同。

我的问题是如何避免User对象的无限递归问题?或者这只是一个糟糕的设计?

1 个答案:

答案 0 :(得分:2)

@JsonManagedReference@JsonBackReference的问题在于它们处理了一种非常特殊的(直接)循环引用,但并不是为了处理那个狭窄窗口之外的任何东西(单个父窗口) object与一个或多个子对象直接相关。不幸的是,您的用例不属于该窗口。

所以你有两个选择:

  • 手动解决方法 - 在序列化顶级order.user对象之前,您需要在服务类中删除(make null)user属性。相反,在序列化user.portfolio.orders之前,您需要删除(make null)orders属性。

  • 框架解决方法 - 升级到Jackson 2.0+并使用@JsonIdentityInfo。它可以正确处理图形中的对象引用,多对多关系,深层对象树等。 Some documentation and examples

如果您可以控制ObjectMapper 也可以解决问题。如果你这样做,你只需要指定一个自定义序列化程序,具体取决于你要返回的对象,但由于你在Spring框架内工作,我不相信你可以直接控制映射器。

我的个人建议是升级您的杰克逊图书馆并使用@JsonIdentityInfo