0

A以前は、REST API エンドポイントの JSON 出力の特定の位置に表示される唯一の型であった既存の classがあります。ただし、現在、共通の基本クラスを拡張してB、すべて から継承するさまざまなタイプの範囲がB出力のその位置に表示されるようにしています。

にタイプ ヒントを追加しましたが、メソッドがタイプ ヒント情報を双方向で正しく検索したFormatsにもかかわらず、リフト json によるシリアル化でタイプ ヒントが無視されました。Formats

Lift-json がタイプ ヒント フィールドを JSON に追加しなかった理由は、Formatsインスタンスでそのクラス用に構成されたカスタム シリアライザーもあり、カスタム シリアライザーがタイプ ヒントをオーバーライドしたためであることが判明しました。

では、カスタム シリアライザーを持ち、タイプ ヒントを発行および生成して、そのタイプを (クライアントとサーバーの両方で) 明確に識別できるクラスを作成するにはどうすればよいでしょうか?

4

1 に答える 1

0

これはもう十分に文書化されていませんが、このTypeHints特性には 2 つのメソッドがあります。

def deserialize: PartialFunction[(String, JObject), Any] = Map()
def serialize: PartialFunction[Any, JObject] = Map()

これらのメソッドは、TypeHintsトレイトを実装するとき (または提供されている の既定の実装を拡張するときTypeHints) にオーバーライドして、型ヒントが指定された JSON オブジェクトのカスタム シリアライゼーションおよびデシリアライゼーション ロジックを指定できます。デフォルトの実装 (上に表示) は、何にも一致しない実質的な部分関数であるため、何の効果もありません。

deserializeのとserializeメソッドにはいくつかの違いがありますSerializer。これは、コードが以前に使用していたものです。

  1. これらのメソッドは引数を取らないため、スコープ内のインスタンスFormatsに依存する必要があります。Formats

  2. JObjectスーパータイプではなく、変換の JSON 側で動作しますJValue(明らかに、考えてみると、型ヒントを持つものはすべて、文字列や数値などではなく、必然的に JSON オブジェクトでなければならないためです)。

  3. それらは型パラメーターをとらずAny、変換の Scala 側でのみ動作します。これは、1 つの大きな部分関数でカスタムのシリアル化ロジックを必要とするすべての型ヒント型を処理するためです。

  4. の代わりにTypeInfodeserialize部分関数はString型ヒント フィールドの値である を受け取ります。

これらの違いのほとんどは、これが、Serializerトレイトが存在する前の古い Lift-json コードであり、カスタムのシリアル化を行う方法が 1 つしかなかったことが原因だと思います。

だから私のために働いたのは:

def typeHints(implicit formats: Formats) = new OurTypeHintsImpl(...タイプヒント情報...) {

override def deserialize = {

case ("type-hint-for-A", o: JObject) =>...既存の逆シリアル化コード...

}

override def deserialize = {

case A(... ) =>...既存の連番コード...

}

また、型ヒントとカスタム シリアル化ロジックの両方を持つ別の型を追加するにcaseは、上記の両方に 1 つの新しいブランチを追加するだけで済みます。

このアプローチでは、lift-json によって正しい型ヒントが自動的に追加されますが、残りのシリアル化と逆シリアル化がどのように行われるかを完全にカスタマイズすることができます。したがって、ほとんどの場合、これが最も便利で適切なアプローチだと思います (ただし、少しリファクタリングが必要でした)。custom で型ヒンティングを再実装することもできるはずSerializerですが、なぜ車輪を再発明するのでしょうか?

警告: 型の大文字と小文字の一致には、デフォルトでジェネリック型に関する制限がありますが、これは通常、この目的では問題になりません。別の型に含まれるジェネリック型を個別にシリアル化するのではなく、代わりに外側の型にマージする場合を除きます。 JSONで。

于 2016-10-08T10:49:49.543 に答える