如何使用 Play Json 序列化和反序列化递归密封特征?



下面给了我一个堆栈溢出错误,我不知道为什么会发生这种情况。 我还试图使递归类型的隐式格式化程序变得懒惰,但我得到了同样的错误。 有什么想法吗?

import play.api.libs.json._
import play.api.libs.functional.syntax._
sealed trait Foo
object Foo {
implicit val fooReads: Reads[Foo] = Reads[Foo] { json =>
(json  "discriminator").validate[String].flatMap {
case "Bar" => json.validate[Bar]
case "Baz" => json.validate[Baz]
}
}
implicit val fooWrites: Writes[Foo] = Writes[Foo] {
case bar: Bar => Json.toJson[Bar](bar)
case baz: Baz => Json.toJson[Baz](baz)
}
}
case class Bar(b: String) extends Foo
object Bar {
implicit val barFormat: OFormat[Bar] = Json.format[Bar]
}
case class Baz(c: String, as: Seq[Foo]) extends Foo
object Baz {
implicit val bazFormat: OFormat[Baz] = (
(__  "c").format[String] and
(__  "as").lazyFormat(implicitly[Format[Seq[Foo]]])
)(Baz.apply, unlift(Baz.unapply))
}
val baz = Baz("aa", Seq(Baz("bb", Seq(Bar("cc")))))
Json.toJson(baz)

更改代码的这一部分以显式调用正确的格式化程序:

implicit val fooWrites: Writes[Foo] = Writes[Foo] {
case bar: Bar => Json.toJson[Bar](bar)(Bar.barFormat)
case baz: Baz => Json.toJson[Baz](baz)(Baz.bazFormat)
}

因为它们都是Foo,所以在识别它们并再次调用您的fooWrites之前,因此堆栈溢出。你也可以看看play-json派生的编解码器,尽管我从来没有用过它。

最新更新