領域物件表示法 (物件映射)

Spring Data REST 會傳回領域物件的表示法,其對應於 HTTP 請求中指定的 Accept 類型。

目前僅支援 JSON 表示法。未來可以透過新增適當的轉換器並使用適當的 content-type 更新控制器方法來支援其他表示法類型。

有時,Spring Data REST 的 ObjectMapper 行為 (已特別配置為使用智慧型序列化器,可將領域物件轉換為連結並再次轉換回來) 可能無法正確處理您的領域模型。資料的結構化方式非常多樣,您可能會發現自己的領域模型無法正確翻譯成 JSON。在這些情況下,嘗試以通用方式支援複雜的領域模型有時也不切實際。有時,根據複雜程度,甚至不可能提供通用的解決方案。

將自訂序列化器和反序列化器新增至 Jackson 的 ObjectMapper

為了容納最大比例的使用案例,Spring Data REST 非常努力地正確呈現您的物件圖。它嘗試將未受管理的 bean 序列化為一般 POJO,並嘗試在必要時建立受管理 bean 的連結。但是,如果您的領域模型不容易進行純 JSON 的讀取或寫入,您可能需要使用自己的自訂映射、序列化器和反序列化器來配置 Jackson 的 ObjectMapper。

抽象類別註冊

您可能需要hook into的一個關鍵配置點是在您的領域模型中使用抽象類別 (或介面) 時。預設情況下,Jackson 不知道要為介面建立哪個實作。請考慮以下範例

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

在預設配置中,當將新資料 POST 到匯出器時,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 的 wiki 上閱讀更多關於 Module 實例如何運作的資訊。

為領域類型新增自訂序列化器

如果您想要以特殊方式序列化或反序列化領域類型,您可以向 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);
}