これはもう十分に文書化されていませんが、このTypeHints
特性には 2 つのメソッドがあります。
def deserialize: PartialFunction[(String, JObject), Any] = Map()
def serialize: PartialFunction[Any, JObject] = Map()
これらのメソッドは、TypeHints
トレイトを実装するとき (または提供されている の既定の実装を拡張するときTypeHints
) にオーバーライドして、型ヒントが指定された JSON オブジェクトのカスタム シリアライゼーションおよびデシリアライゼーション ロジックを指定できます。デフォルトの実装 (上に表示) は、何にも一致しない実質的な部分関数であるため、何の効果もありません。
deserialize
のとserialize
メソッドにはいくつかの違いがありますSerializer
。これは、コードが以前に使用していたものです。
これらのメソッドは引数を取らないため、スコープ内のインスタンスFormats
に依存する必要があります。Formats
JObject
スーパータイプではなく、変換の JSON 側で動作しますJValue
(明らかに、考えてみると、型ヒントを持つものはすべて、文字列や数値などではなく、必然的に JSON オブジェクトでなければならないためです)。
それらは型パラメーターをとらずAny
、変換の Scala 側でのみ動作します。これは、1 つの大きな部分関数でカスタムのシリアル化ロジックを必要とするすべての型ヒント型を処理するためです。
の代わりにTypeInfo
、deserialize
部分関数は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で。