Domain Object Representations (Object Mapping)

Spring Data REST 返回在 HTTP 请求中指定的 “Accept” 类型对应的域对象的表述。 当前,仅支持 JSON 表述。其他表述类型可以通过添加适当的转换器并将控制器方法更新为适当的内容类型在将来得到支持。 有时,Spring Data REST “ObjectMapper” 的行为(已专门配置为使用可以将域对象变为链接再变回来的智能序列化器)可能无法正确处理你的域模型。你可以组织数据的方式有很多种,你可能会发现自己的域模型无法正确翻译为 JSON。有时候在这些情况下尝试用一般的方式支持一个复杂的域模型也不实际。有时,根据复杂度,甚至无法提供一般解决方案。

Adding Custom Serializers and Deserializers to Jackson’s ObjectMapper

为了适应大多数用例,Spring Data REST 非常努力地正确呈现你的对象图。它尝试将非托管 Bean 序列化为正常的 POJO,并且在需要时尝试创建到托管 Bean 的链接。然而,如果你的域模型本身不适合于读取或写入纯 JSON,你可以使用自己的自定义映射、序列化器和反序列化器对 Jackson 的 ObjectMapper 进行配置。

Abstract Class Registration

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

@Entity
public class MyEntity {
  @OneToMany
  private List<MyInterface> interfaces;
}

在默认配置中,当向导出器发布新数据时,Jackson 不知道实例化哪个类。这是你需要通过注释或(更干净地)使用 “Module” 注册类型映射来告诉 Jackson 的。

要将你自己的 Jackson 配置添加到 Spring Data REST 使用的 “ObjectMapper”,请覆盖 “configureJacksonObjectMapper” 方法。该方法会传递一个 “ObjectMapper” 实例,该实例有一个特殊模块来处理序列化和反序列化 “PersistentEntity” 对象。你也可以注册你自己的模块,如下例所示:

@Override
protected void configureJacksonObjectMapper(ObjectMapper objectMapper) {

  objectMapper.registerModule(new SimpleModule("MyCustomModule") {

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

一旦您在 Module 中访问了 SetupContext 对象,您就可以执行各种很酷的操作来配置 Jackson 的 JSON 映射。您可以在 Jackson’s wiki 上阅读有关 Module 实例如何工作的更多信息。

Adding Custom Serializers for Domain Types

如果你想以一种特殊的方式序列化或反序列化域类型,你可以向 Jackson 的 “ObjectMapper” 注册你自己的实现,Spring Data REST 导出器会透明地正确处理那些域对象。要从你的 “setupModule” 方法实现中添加序列化器,你可以执行类似以下操作:

@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);
}