杰克逊与 Spring Boot 基于深度的序列化

Posted

技术标签:

【中文标题】杰克逊与 Spring Boot 基于深度的序列化【英文标题】:Jackson with Spring Boot depth-based serialization 【发布时间】:2018-02-03 20:54:50 【问题描述】:

在我们的 Spring Boot (1.5.6) 应用程序中,我们的实体中有一个经典的双向 OneToMany 层次结构,例如一个Order 有很多Item

public class Order 

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @OneToMany(mappedBy = "order", )
    @JsonManagedReference
    private Set<Item> items = new HashSet<>();
    // getters and setters

 

public class Item 

   @Id
   @GeneratedValue(strategy = GenerationType.AUTO)
   private Long id;

   @ManyToOne
   @JsonBackReference
    private Order order = new HashSet<>();
    // getters and setters

 

在我们的 javascript 视图中,它使用休息控制器来获取数据,有时 Order 有时 Items 是根对象。假设我们有某种“显示顺序”和另一个“显示项目”视图。

所以,如果Order 是根,我们还想知道它的子项(项目),如果Item 是根,我们还想知道它的父顺序。

序列化显然会产生无限递归,所以我们通常会在这里使用@JsonManagedReference@JsonBackReference。 但是,这删除了反向引用(所以我们在这里有一个单向序列化......)。我们还尝试使用JsonIdentityInfo - 这不起作用,因为elasticsearch在反序列化过程中存在一些问题,而且我们也有一些交叉引用,它们也将被ID替换并搞砸一切......

长话短说,我们现在的想法是进行某种“深度突破”:

当第一个序列化对象是Order,那么它的items-property 应该被完全序列化。但是对于每个Item,对order 的反向引用不应被序列化(可以在这里说“顺序深度为2”)。 当第一个序列化对象是 Item 时,其反向引用 order 将被序列化,但对项的第二个托管引用将被忽略。

我们也为此尝试了 JsonView,但我们无法动态设置此值。

任何人解决了这个问题或有我们可以使用的方法?

【问题讨论】:

【参考方案1】:

除了@JsonManagedReference@JsonBackReference,您可以使用@JsonIgnoreProperties 注释来抑制嵌套属性的序列化:

public class Item 

   //...

   @JsonIgnoreProperties("items") 
   @ManyToOne
   private Order order = new HashSet<>();

   //...
 

【讨论】:

哦该死 - 这么简单 - 不知道这个......谢谢! 这是完美的。来自未来的感谢

以上是关于杰克逊与 Spring Boot 基于深度的序列化的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 升级后 Jackson 序列化不起作用

Spring boot,Jackson Json 在序列化和反序列化时出现问题

设置杰克逊功能 WRITE_DATES_AS_TIMESTAMPS 在 Spring Boot 中不起作用

如何动态忽略杰克逊序列化的属性

在 Spring Boot 端点上使用自定义杰克逊映射器

Spring Boot Jackson - 根据深度选择性序列化嵌入式对象属性