Scala play json:如何捕获整个JSON源代码?

v440hwme  于 2023-05-02  发布在  Scala
关注(0)|答案(2)|浏览(144)

在我的客户机中,我接收一个WSResponse,并使用play的deserializeJson方法提取数据,这些数据由路径e指定。g的。

implicit val lsmf: Format[MyData] = (
    (__).formatNullable[JsValue] ~
    (__ \ "id").format[Int] ~
    (__ \ "name").format[String])
  (MyData.apply, unlift(MyData.unapply))

接收类将看起来像

case class MyData(
    json: JsValue,
    id:   Int,
    name: String) {...}

解析数据的第一个成员应该包含接收到的整个JSON。
我不知道我怎么能完成它。如果我将路径指定为(__),这是一个错误的路径,解析器将失败。如果我将路径指定为(__ \ ""),解析器将查找名为""的字段,这显然是缺失的。
除了手动解析(用我自己的双手)之外,还有什么合理的解决方案吗?

eh57zj3b

eh57zj3b1#

有一种方法:

implicit val reads: Reads[MyData] = (json: JsValue) => {
  val id = (json \ "id").as[Int] // or another way to extract it
  // Same for other fields...
  MyData(json, id, name)
}

// Do you even need a Writes? Not sure it makes much sense.
implicit val writes: Writes[MyData] = (data: MyData) => {
  data.json
  // Or:
  JsObject("id" -> JsNumber(data.id), ...)
}

另一种方法是通过使用 Package 器case类来依赖Play的宏:

case class ActualData(id: Long, name: String)

case class MyData(json: JsValue, data: ActualData)

implicit val actualFormat: Format[ActualData] = Json.format[ActualData]

implicit val myReads: Reads[MyData] = (json: JsValue) => {
  MyData(json, json.as[ActualData])
}

第二种方法的好处是,如果数据发生变化,可以自动调整,而不必更新解析器。

fwzugrvs

fwzugrvs2#

如果fields of your case class具有same fields and types of json fields,则不需要进行手动Map。您可以直接使用隐式瓦尔,使用Json.writes[A]进行序列化,使用Json.reads[A]进行反序列化,或使用Json.format[A]进行序列化和反序列化。
这里的官方文档展示了如何做json automated mapping

相关问题