Chris Chris - 5 months ago 29
JSON Question

How to read a JSON string with escaped quotes in Play

I'm receiving some JSON from a server:


For why I am getting this odd looking JSON see this question. I've written some code to parse this bit of the object:

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

But I am getting an error:


Which is a little weird because the path \"action\" is exactly what we are looking for.

m-z m-z

The reason those quotes are escaped is that the "payload" key actually has the String type, so it contains a string representation of an object. This is a very weird for a server to return, really. You will essentially need to re-parse the contents of payload's value, or pre-process the JSON. This can all be done with Play's JSON API, though.

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


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),)