Scala コードで JSON オブジェクトを操作するために json4s を使用しています。JSON データを内部表現に変換したいと考えています。次の学習テストは、私の問題を示しています。
"Polimorphic deserailization" should "be possible" in {
import org.json4s.jackson.Serialization.write
val json =
"""
|{"animals": [{
| "name": "Pluto"
| }]
|}
""".stripMargin
implicit val format = Serialization.formats(ShortTypeHints(List(classOf[Dog], classOf[Bird])))
val animals = parse(json) \ "animals"
val ser = write(Animals(Dog("pluto") :: Bird(canFly = true) :: Nil))
System.out.println(ser)
// animals.extract[Animal] shouldBe Dog("Pluto") // Does not deserialize, because Animal cannot be constructed
}
動物のリストを持つ JSON オブジェクトがあるとします。Animal
は抽象型であるため、インスタンス化できません。Dog
代わりに、JSON 構造を解析して、またはBird
オブジェクトのいずれかを返したいと考えています。それらは異なる署名を持っています:
case class Dog(name: String) extends Animal
case class Bird(canFly: Boolean) extends Animal
それらの署名は異なるため、JSON オブジェクトにクラス タグがなくても識別できます。(正確には、私が受け取った JSON 構造はそれらのタグを提供しません)。
Animal オブジェクトのリストをシリアル化しようとしました (コードを参照)。結果は次のとおりです。Ser: {"animals":[{"jsonClass":"Dog","name":"pluto"},{"jsonClass":"Bird","canFly":true}]}
ご覧のとおり、シリアル化するときに、json4s は class-tag を追加しjsonClass
ます。
このようなタグを提供しない JSON オブジェクトをデシリアライズするにはどうすればよいですか? 拡張することでこれを達成することは可能TypeHints
ですか?
同様の質問も見つけました: [json4s]:Extracting Array of different objects with a solution that uses generics instead of subclassing. ただし、私が正しく理解していれば、このソリューションでは単純に json オブジェクトを渡して内部表現を持つことはできません。代わりに、そうでないフォームを選択する必要がありますNone
(継承階層で可能なすべてのタイプをチェックしながら)。JSON 構造のさまざまな深さに複数のポリモーフィック クラスがあるため、これは少し面倒です。