简体   繁体   English

Spring Boot + Jackson:根据所调用的REST API以不同的方式序列化对象

[英]Spring Boot + Jackson: Serialize an object in different ways depending on the called REST API

I am developing a Spring Boot web application that exposes REST APIs and I have trouble with JSON Serialization. 我正在开发一个公开REST API的Spring Boot Web应用程序,并且在JSON序列化方面遇到麻烦。

Let's say I have two classes A and B, that are in a one-to-many bidirectional relationship. 假设我有两个类A和B,它们是一对多的双向关系。

This means that I have something like this: 这意味着我有这样的事情:

public class A {
    private List<B> bList;
    ...
}

and

public class B {
    private A owner;
    ...
}

When it comes to JSON serialize this, of course there is a loop. 当涉及到JSON序列化时,当然会有一个循环。

And this is my problem: 这是我的问题:

  • In API methods that focus on A (eg "give me the list of all As in the DB"), I would like a JSON serialization in which: 在专注于A API方法中(例如“向我提供数据库中所有As的列表”),我想要JSON序列化,其中:
    • A objects do contain the list of B s A对象确实包含B的列表
    • B objects do not contain their A owner B对象不包含其A所有者
  • In API methods that focus on B (eg "give me the list of all B s in the DB"), I would like a JSON serialization in which: 在关注B API方法中(例如“给我DB中所有B的列表”),我想要一个JSON序列化,其中:
    • A objects do not contain the list of their B s A对象不包含其B的列表
    • B objects do contain their A owner B对象确实包含其A所有者

I believe I could get it to work with @JsonView annotations, but I do not think it is an elegant solution. 我相信我可以将其与@JsonView注释一起使用,但是我认为这不是一个优雅的解决方案。 In my application (which has more than two classes) I'd need to create and manage at least 4 or 5 JsonViews: so in my model classes, for each attribute I'd have to manage a messy bunch of @JsonView annotations. 在我的应用程序(具有两个以上的类)中,我需要创建和管理至少4或5个JsonViews:因此,在我的模型类中,对于每个属性,我必须管理一堆凌乱的@JsonView批注。 On the contrary, I believe that model classes should not be aware of the fact that they have different JSON representations depending on the API method. 相反,我认为模型类不应意识到这样的事实,即它们根据API方法具有不同的JSON表示形式。

I searched how to use custom JSON serializers, and found that Jackson allows to do that with its SimpleModule. 我搜索了如何使用自定义JSON序列化程序,并发现Jackson允许使用其SimpleModule进行此操作。 However it seems that the SimpleModule does not allow to choose which serializer to use on a case-by-case basis (it just always uses the last added Serializer). 但是,似乎SimpleModule不允许视情况选择要使用的序列化程序(它始终使用最后添加的序列化程序)。

So I am a bit clueless now. 所以我现在有点笨了。 Does anybody know a clean way to allow the Controllers choose how to serialize a Class? 有人知道允许控制器选择如何序列化类的一种干净方法吗?

I think you should use DTO here, you could use different DTO for different endpoints, and you could choose which fields you want to include or exclude. 我认为您应该在此处使用DTO ,可以对不同的终结点使用不同的DTO ,并且可以选择要包括或排除的字段。 Also, you could decorate them if you need so. 另外,如果需要,可以装饰它们。

Here you have a list of benefits of using DTO in your endpoints: REST API - DTOs or not? 在这里,您有在端点中使用DTO的好处的列表: REST API-是否使用DTO

Use @JsonIdentityInfo 使用@JsonIdentityInfo

Your question has answer over here: Jackson - serialization of entities with birectional relationships (avoiding cycles) 您的问题已在此处回答: Jackson-具有双向关系的实体的序列化(避免循环)

You can use the @JsonIdentityInfo annotation with entities or use @JsonManagedReference , @JsonBackReference . 您可以对实体使用@JsonManagedReference批注,也可以使用@JsonIdentityInfo@JsonBackReference

You can even ignore one side of the relationship with @JsonIgnore or @JsonView . 您甚至可以使用@JsonIgnore@JsonView忽略关系的@JsonView

If you want to mange serialization / unserialization by yourself, use custom implementations (eg with @JsonDeserialize ). 如果要自己管理序列化/反序列化,请使用自定义实现(例如@JsonDeserialize )。

Eugen provided a nice tutorial on this. Eugen为此提供了很好的教程

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

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