在scala / play中解析“ stringified” JSON

ndx

我正在实现一个Scala / Play API(apiA),它消耗了我无法控制的API(apiB)。ApiB返回JSON响应,在某些情况下,JSON响应已嵌入字符串中。例:

{
  "name":"some_name",
  "scores": "[[10,15]]",
  "data": "{\"attr1\":\"value1\",\"attr2\":\"value3\"}"
}

ApiA需要name在将所有数据传递到客户端之前访问的值,并且应将其作为适当的JSON提供给客户端。我正在考虑将原始响应解析为

case class Response(name: String, scores: JsValue, data: JsValue)

要么

case class Response(name: String, scores: Seq[Seq[Int]], data: Map[String, String])

现在,只要不是包含JSON的字符串scoresdata将其解析为哪种类型都没有关系。

现在,如果JSON响应格式正确,那么编写格式/读取/写入将很简单,但是我在解决如何将内容转换为JSON解析为最终类型之前有点犹豫。

任何帮助,将不胜感激。

尚特佩
case class Response(name: String, scores: Seq[Seq[Int]], data: Map[String, String])

import play.api.libs.json._

val stringified = Reads[JsValue] {
  _.validate[String].flatMap { raw =>
    try {
      JsSuccess(Json.parse(raw))
    } catch {
      case cause =>
        JsError(cause.getMessage)
    }
  }
}

implicit val respReads = Reads[Response] { js =>
  for {
    name <- (js \ "name").validate[String]
    scores <- (js \ "scores").validate(
      stringified).flatMap(_.validate[Seq[Seq[Int]]])
    data <- (js \ "data").validate(
      stringified).flatMap(_.validate[Map[String, String]])
  } yield Response(name, scores, data)
}

Json.parse("""{
  "name":"some_name",
  "scores": "[[10,15]]",
  "data": "{\"attr1\":\"value1\",\"attr2\":\"value3\"}"
}""").validate[Response]
// JsSuccess(Response(some_name,Vector(Vector(10, 15)),Map(attr1 -> value1, attr2 -> value3)),)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章