将自定义序列化器和反序列化器添加到 Jackson 的 ObjectMapper

有时,Spring Data REST 的 ObjectMapper(已专门配置为使用智能序列化器,这些序列化器可以将领域对象转换为链接,然后再转换回来)的行为可能无法正确处理您的领域模型。您可以采用多种方式组织数据,这可能导致您自己的领域模型无法正确转换为 JSON。在这些情况下,以通用方式支持复杂的领域模型有时也不切实际。有时,取决于复杂程度,甚至无法提供通用的解决方案。

为了适应绝大多数用例,Spring Data REST 尝试正确渲染您的对象图。它尝试将非受管 bean 序列化为普通 POJO,并在必要时尝试创建指向受管 bean 的链接。但是,如果您的领域模型不容易用于读取或写入纯 JSON,您可能希望使用自己的自定义类型映射和(反)序列化器来配置 Jackson 的 ObjectMapper

抽象类注册

您可能需要关注的一个关键配置点是当您在领域模型中使用抽象类(或接口)时。默认情况下,Jackson 不知道为接口创建什么实现。考虑以下示例

@Entity
public class MyEntity {

  @OneToMany
  private List<MyInterface> interfaces;
}

在默认配置下,当向 exporter POST 新数据时,Jackson 不知道要实例化哪个类。您需要通过注解或者更简洁的方式,即使用 Module 注册类型映射来告知 Jackson。

在您的 ApplicationContext 范围内声明的任何 Module bean 都将被 exporter 获取并注册到其 ObjectMapper 中。要添加这种特殊的抽象类类型映射,您可以创建一个 Module bean,并在 setupModule 方法中添加一个适当的 TypeResolver,如下所示

public class MyCustomModule extends SimpleModule {

  private MyCustomModule() {
    super("MyCustomModule", new Version(1, 0, 0, "SNAPSHOT"));
  }

  @Override
  public void setupModule(SetupContext context) {
    context.addAbstractTypeResolver(
      new SimpleAbstractTypeResolver().addMapping(MyInterface.class,
        MyInterfaceImpl.class));
  }
}

一旦您在 Module 中访问了 SetupContext 对象,您就可以进行各种有趣的操作来配置 Jackson 的 JSON 映射。您可以在 Jackson 的 wiki 上阅读更多关于 Modules 的工作原理

为领域类型添加自定义序列化器

如果您想以特殊方式序列化或反序列化领域类型,您可以将自己的实现注册到 Jackson 的 ObjectMapper 中。然后 Spring Data REST exporter 将透明地正确处理这些领域对象。

要在 setupModule 方法实现中添加序列化器,您可以执行如下操作

public class MyCustomModule extends SimpleModule {

  …

  @Override
  public void setupModule(SetupContext context) {

    SimpleSerializers serializers = new SimpleSerializers();
    SimpleDeserializers deserializers = new SimpleDeserializers();

    serializers.addSerializer(MyEntity.class, new MyEntitySerializer());
    deserializers.addDeserializer(MyEntity.class, new MyEntityDeserializer());

    context.addSerializers(serializers);
    context.addDeserializers(deserializers);
  }
}

借助前面示例中所示的自定义模块,当您的领域对象对于 Spring Data REST 尝试涵盖的 80% 通用用例来说过于复杂时,Spring Data REST 可以正确处理它们。