ドメインオブジェクト表現 (オブジェクトマッピング)
Spring Data REST は、HTTP リクエストで指定された Accept
型に対応するドメインオブジェクトの表現を返します。
現在、JSON 表現のみがサポートされています。将来的には、適切なコンバーターを追加し、コントローラーメソッドを適切なコンテンツ型で更新することにより、他の表現型をサポートできます。
場合によっては、Spring Data REST ObjectMapper
(ドメインオブジェクトをリンクに変換して元に戻すことができるインテリジェントシリアライザーを使用するように特別に構成されている) の動作が、ドメインモデルを正しく処理しない場合があります。データを構造化する方法はたくさんあるため、独自のドメインモデルが JSON に正しく変換されない場合があります。また、これらの場合、複雑なドメインモデルを一般的なメソッドでサポートしようとすることは実用的ではない場合もあります。複雑さによっては、一般的なソリューションを提供することさえ不可能な場合があります。
Jackson の ObjectMapper へのカスタムシリアライザーとデシリアライザーの追加
ユースケースの最大の割合に対応するために、Spring Data REST はオブジェクトグラフを正しくレンダリングするために非常に懸命に試みます。アンマネージド Bean を通常の POJO として直列化しようとし、必要に応じてマネージド Bean へのリンクを作成しようとします。ただし、ドメインモデルがプレーン JSON の読み取りまたは書き込みに適していない場合は、独自のカスタムマッピング、シリアライザー、デシリアライザーを使用して Jackson の ObjectMapper を構成することをお勧めします。
抽象クラス登録
フックする必要があるかもしれない重要な構成ポイントの 1 つは、ドメインモデルで抽象クラス(またはインターフェース)を使用する場合です。デフォルトでは、Jackson はインターフェース用に作成する実装を認識していません。次の例を考えてみましょう。
@Entity
public class MyEntity {
@OneToMany
private List<MyInterface> interfaces;
}
デフォルトの構成では、Jackson は、新しいデータをエクスポーターに POST するときにインスタンス化するクラスを認識していません。これは、アノテーションを介して、または(よりクリーンに) Module
を使用して型マッピングを登録することによって Jackson に伝える必要があるものです。
Spring Data REST によって使用される ObjectMapper
に独自の Jackson 構成を追加するには、configureJacksonObjectMapper
メソッドをオーバーライドします。このメソッドには、PersistentEntity
オブジェクトのシリアライズおよびデシリアライズを処理する特別なモジュールを持つ ObjectMapper
インスタンスが渡されます。次の例に示すように、独自のモジュールを登録することもできます。
@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 マッピングを構成するためにあらゆる種類の優れた処理を実行できます。Module
インスタンスが Jackson のウィキ (英語) でどのように機能するかについて詳しく読むことができます。
ドメイン型のカスタムシリアライザーの追加
特別なメソッドでドメイン型をシリアライズまたはデシリアライズしたい場合は、独自の実装を 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);
}