此版本仍在开发中,尚未被视为稳定版本。如需最新稳定版本,请使用 Spring Data REST 5.0.4spring-doc.cadn.net.cn

领域对象表示(对象映射)

Spring Data REST 返回一个领域对象的表示形式,该表示形式对应于 HTTP 请求中指定的 Accept 类型。spring-doc.cadn.net.cn

目前仅支持 JSON 格式的表示。未来可以通过添加适当的转换器,并使用相应的内容类型(content-type)更新控制器方法,以支持其他类型的表示。spring-doc.cadn.net.cn

有时,Spring Data REST 的 ObjectMapper(已专门配置为使用智能序列化器,能够将领域对象转换为链接并可反向转换)可能无法正确处理您的领域模型。由于数据结构的方式多种多样,您可能会发现自己的领域模型未能被正确地转换为 JSON。在这些情况下,试图以通用方式支持复杂的领域模型有时并不现实。有时,根据复杂程度的不同,甚至根本无法提供通用的解决方案。spring-doc.cadn.net.cn

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

为了适应绝大多数使用场景,Spring Data REST 会尽最大努力正确地渲染您的对象图。它会尝试将非托管的 Bean 作为普通 POJO 进行序列化,并在必要时为托管的 Bean 创建链接。然而,如果您的领域模型难以直接通过纯 JSON 进行读写,您可能需要使用自定义的映射、序列化器和反序列化器来配置 Jackson 的 ObjectMapper。spring-doc.cadn.net.cn

抽象类注册

您可能需要介入的一个关键配置点是在您的领域模型中使用抽象类(或接口)时。默认情况下,Jackson 并不知道应该为一个接口创建哪种实现。请考虑以下示例:spring-doc.cadn.net.cn

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

在默认配置下,当向导出器(exporter)发送 POST 请求以提交新数据时,Jackson 并不知道应该实例化哪个类。你需要通过注解,或者(更清晰的方式)通过使用 Module 注册类型映射来告知 Jackson。spring-doc.cadn.net.cn

要将您自己的 Jackson 配置添加到 Spring Data REST 所使用的 ObjectMapper 中,请重写 configureJacksonObjectMapper 方法。 该方法会接收到一个 MapperBuilder 实例,该实例包含一个特殊模块,用于处理 PersistentEntity 对象的序列化和反序列化。 您也可以注册自己的模块,如下例所示:spring-doc.cadn.net.cn

@Override
public void configureJacksonObjectMapper(MapperBuilder<? extends ObjectMapper, ? extends MapperBuilder<?, ?>> mapperBuilder) {

  mapperBuilder.addModule(new SimpleModule("MyCustomModule") {

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

一旦你在自己的 SetupContext 中获得了 Module 对象,就可以执行各种酷炫的操作来配置 Jackson 的 JSON 映射。 你可以在 Jackson 的 Wiki 上了解更多关于 https://github.com/FasterXML/jackson-databind/wiki/JacksonFeatures 实例的工作原理。spring-doc.cadn.net.cn

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

如果你想以特殊方式序列化或反序列化某个领域类型,可以向 Jackson 的 ObjectMapper 注册你自己的实现,Spring Data REST 导出器会透明地正确处理这些领域对象。要从你的 setupModule 方法实现中添加序列化器,你可以执行如下操作:spring-doc.cadn.net.cn

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