Scala play json嵌套循环依赖json解析

xytpbqjk  于 2023-03-02  发布在  Scala
关注(0)|答案(1)|浏览(129)

我有3个用例类,它们相互循环引用嵌套字段,如下所示。

case class DataSource(subQuery: Query,name:String)
case class JoinQuery(joinType:String,query:Query)
case class Query(child:DataSource, joinQuery:Seq[JoinQuery])

我想用Json格式器类为这些写一个伴随类来解析json到case类,反之亦然。我怎么能做到呢?我尝试了下面提到的answer,但没有运气。

khbbv19g

khbbv19g1#

我尝试了下面提到的answer,但没有运气。
对不起,但这不是一个适当的描述你做了什么,你得到了什么错误。
没有NullPointerException s,我无法使automated mappings工作,但是使用递归类型的方法似乎可以工作。
DataSource依赖于QueryQuery依赖于DataSource,所以不清楚如何示例化这些类,可能用null s,所以至少有一些字段应该是可选的,比如我修改了这个地方:case class Query(child:Option[DataSource], ...)

import play.api.libs.json._
import play.api.libs.functional.syntax._

case class DataSource(subQuery: Query,name:String)
object DataSource {
  implicit lazy val reads: Reads[DataSource] = (
    (__ \ "subQuery").lazyRead(Reads.of[Query](Query.reads)) and
      (__ \ "name").read[String]
    )(DataSource.apply _)

  implicit lazy val writes: Writes[DataSource] = (
    (__ \ "subQuery").lazyWrite(Writes.of[Query](Query.writes)) and
      (__ \ "name").write[String]
    )(unlift(DataSource.unapply))
}

case class JoinQuery(joinType:String,query:Query)
object JoinQuery {
  implicit lazy val reads: Reads[JoinQuery] = (
    (__ \ "joinType").read[String] and
      (__ \ "query").lazyRead(Reads.of[Query](Query.reads))
    )(JoinQuery.apply _)

  implicit lazy val writes: Writes[JoinQuery] = (
    (__ \ "joinType").write[String] and
      (__ \ "query").lazyWrite(Writes.of[Query](Query.writes))
    )(unlift(JoinQuery.unapply))
}

case class Query(child:Option[DataSource], joinQuery:Seq[JoinQuery])
object Query {
  implicit lazy val reads: Reads[Query] = (
    (__ \ "child").lazyRead(Reads.optionWithNull[DataSource](DataSource.reads)) and
      (__ \ "joinQuery").lazyRead(Reads.seq[JoinQuery](JoinQuery.reads))
    )(Query.apply _)

  implicit lazy val writes: Writes[Query] = (
    (__ \ "child").lazyWrite(Writes.optionWithNull[DataSource](DataSource.writes)) and
      (__ \ "joinQuery").lazyWrite(Writes.seq[JoinQuery](JoinQuery.writes))
    )(unlift(Query.unapply))
}

Json.parse(
  """{"subQuery":{"child":{"subQuery":{"child":null,"joinQuery":[]},"name":"b"},"joinQuery":[{"joinType":"c","query":{"child":null,"joinQuery":[]}}]},"name":"a"}"""
).as[DataSource])
// DataSource(Query(Some(DataSource(Query(None,List()),b)),List(JoinQuery(c,Query(None,List())))),a)

Json.stringify(Json.toJson(
  DataSource(Query(Some(DataSource(Query(None, Seq()), "b")), Seq(JoinQuery("c", Query(None, Seq())))), "a")
))
// {"subQuery":{"child":{"subQuery":{"child":null,"joinQuery":[]},"name":"b"},"joinQuery":[{"joinType":"c","query":{"child":null,"joinQuery":[]}}]},"name":"a"}

相关问题