Adding Custom Serializers and Deserializers to Jackson’s ObjectMapper

有时候,Spring Data REST ObjectMapper(已专门配置为使用可将域对象转换为链接然后再返回的可理解序列化程序)的行为可能无法正确处理您的域模型。您可以用多种方式来构建数据,从而发现自己无法将域模型正确转换为 JSON。而且,在这些情况下,以通用方式支持复杂的域模型有时也不切实际。有时,根据复杂性,甚至无法提供一个通用的解决方案。 为了适应大多数用例,Spring Data REST 会尝试正确渲染对象图。它会尝试将非托管 Bean 序列化为常规 POJO,并尝试在需要时创建到托管 Bean 的链接。但是,如果您的域模型无法轻松地用于读取或写入纯 JSON,您可能希望使用您自己的自定义类型映射和(反)序列化程序来配置 Jackson 的 ObjectMapper

Abstract Class Registration

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

@Entity
public class MyEntity {

  @OneToMany
  private List<MyInterface> interfaces;
}

在默认配置中,当将新数据 POST 到导出程序时,Jackson不知道要实例化哪个类。您需要通过注释或通过使用 Module注册类型映射来告诉 Jackson。

ApplicationContext 范围内声明的任何 模块 Bean 都将由导出程序选取并用其 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 对象,您就可以执行各种很酷的操作来配置 Jackon 的 JSON 映射。您可以阅读有关如何 Modules work on Jackson’s wiki 的更多信息。

Adding Custom Serializers for Domain Types

如果您想以特别方式序列化或反序列化域类型,可以使用 Jackson 的 ObjectMapper 注册您自己的实现。然后,Spring Data REST 导出程序会透明地正确处理那些域对象。

若要从 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 正确处理你的域对象。