如何在Play中读取带有转义引号的JSON字符串

时间:2016-08-06 13:24:50

标签: json scala playframework

我从服务器接收了一些JSON:

"payload":"{\"action\":\"schedule\"}"

为什么我会看到这个奇怪的JSON,请看this question。我已经编写了一些代码来解析对象的这一部分:

  implicit val botPayloadReads: Reads[BotPayload] = (
    (JsPath \ """\"action\"""").read[String] and
      (JsPath \ """\"returnToAction"""").readNullable[String]
    )(BotPayload.apply _)

但是我收到了一个错误:

List((/entry(0)/messaging(0)/postback/payload/\"action\",List(ValidationError(List(error.path.missing),WrappedArray()))))

这有点奇怪,因为路径\" action \"正是我们正在寻找的。

1 个答案:

答案 0 :(得分:1)

这些引号被转义的原因是"payload"键实际上具有String类型,因此它包含对象的字符串表示形式。真的,这对于服务器返回来说非常奇怪。您基本上需要重新解析payload的值的内容,或者预处理JSON。不过,这可以通过Play的JSON API完成。

import play.api.data.validation.ValidationError
import play.api.libs.json._
import scala.util.{ Success, Try }

case class BotPayload(action: String, returnToAction: Option[String])

object BotPayload {

  val payloadReads = Json.reads[BotPayload]

  implicit val reads: Reads[BotPayload] = Reads.StringReads
    .map(s => Try(Json.parse(s)))
    .collect(ValidationError("Cound not parse content of payload")) {
      case Success(js) => js
    }
    .andThen(payloadReads)

}

scala> val js = Json.parse(""" {"payload":"{\"action\":\"schedule\"}"} """)
js: play.api.libs.json.JsValue = {"payload":"{\"action\":\"schedule\"}"}

scala> (js \ "payload").validate[BotPayload]
res0: play.api.libs.json.JsResult[BotPayload] = JsSuccess(BotPayload(schedule,None),)