【问题标题】:Spring Boot + Jackson: Serialize an object in different ways depending on the called REST APISpring Boot + Jackson:根据调用的 REST API 以不同的方式序列化对象
【发布时间】:2018-10-16 09:10:32
【问题描述】:

我正在开发一个公开 REST API 的 Spring Boot Web 应用程序,但我遇到了 JSON 序列化问题。

假设我有两个类 A 和 B,它们是一对多的双向关系。

这意味着我有这样的东西:

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

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

说到JSON序列化这个,当然是有循环的。

这是我的问题:

  • 在专注于A 的 API 方法中(例如“给我数据库中所有 As 的列表”),我想要一个 JSON 序列化,其中:
    • A 对象确实包含 Bs 的列表
    • B 对象不包含其 A 所有者
  • 在专注于 B 的 API 方法中(例如“给我数据库中所有 Bs 的列表”),我想要一个 JSON 序列化,其中:
    • A 对象不包含其Bs 的列表
    • B 对象确实包含其 A 所有者

我相信我可以让它与@JsonView 注释一起使用,但我认为这不是一个优雅的解决方案。在我的应用程序(有两个以上的类)中,我需要创建和管理至少 4 或 5 个 JsonView:所以在我的模型类中,对于每个属性,我必须管理一堆乱七八糟的 @JsonView 注释。相反,我认为模型类不应该意识到它们具有不同的 JSON 表示,具体取决于 API 方法。

我搜索了如何使用自定义 JSON 序列化程序,发现 Jackson 允许使用其 SimpleModule 来做到这一点。然而,SimpleModule 似乎不允许根据具体情况选择使用哪个序列化器(它总是使用最后添加的序列化器)。

所以我现在有点不知所措。有人知道让控制器选择如何序列化类的干净方法吗?

【问题讨论】:

    标签: java json spring-boot jackson json-serialization


    【解决方案1】:

    我认为你应该在这里使用DTO,你可以为不同的端点使用不同的DTO,你可以选择你想要包含或排除的字段。此外,如果需要,您可以装饰它们。

    这里列出了在端点中使用 DTO 的好处:REST API - DTOs or not?

    【讨论】:

      【解决方案2】:

      使用@JsonIdentityInfo

      你的问题在这里有答案:Jackson - serialization of entities with birectional relationships (avoiding cycles)

      【讨论】:

        【解决方案3】:

        您可以对实体使用@JsonIdentityInfo 注解或使用@JsonManagedReference@JsonBackReference

        您甚至可以忽略与@JsonIgnore@JsonView 的关系的一侧。

        如果您想自己管理序列化/反序列化,请使用自定义实现(例如使用@JsonDeserialize)。

        Eugen 为此提供了一个很好的tutorial

        【讨论】:

        • 正如我所说,我需要根据 API 方法以不同的方式序列化对象。所以我猜@JsonManagedReference、JsonBackReference 和 JsonIgnore 不在讨论之列,因为它们总是以相同的方式序列化,独立于特定调用(我说得对吗?)。即使是单个自定义序列化程序也不够:我需要多个。所以我 JsonDeserialize 也没有用。正如我所说,JsonView 可以解决问题,但方式非常混乱。我认为模型类不应该知道它们是如何被序列化的,尤其是在序列化逻辑很复杂的情况下。
        • 就您的确切用例而言,提到的第一个注释可能是最匹配的注释。我也提到了其他可能性,因为它们可能仍然是一种选择,至少对于有类似问题的其他用户而言。
        猜你喜欢
        • 2018-11-17
        • 2020-05-25
        • 2021-02-18
        • 2017-09-09
        • 2020-07-17
        • 1970-01-01
        • 1970-01-01
        • 2020-07-27
        • 2018-06-15
        相关资源
        最近更新 更多