jk-kim
jk-kim

Reputation: 1186

How can I disable Scala Play json's backslash escape in `JsObject.toString()`?

I cannot find a way to print a single backslash as a single backslash within Play json. Is this something possible?

scala> val k = """abc\edf"""
val k: String = abc\edf

scala> JsString(k)
val res80: play.api.libs.json.JsString = "abc\\edf"

scala> JsString(k).toString()
val res81: String = "abc\\edf"     // <--- additional "\" appears

scala> JsString(k).as[String]
val res82: String = abc\edf        // <--- this is the string that I need

scala> Json.stringify(JsString(k))
val res86: String = "abc\\edf"

scala> Json.asciiStringify(JsString(k))
val res90: String = "abc\\edf"

scala> Json.prettyPrint(JsString(k))
val res92: String = "abc\\edf"

Normally this would be fine as I can just use as[String]. But if this value is within object I cannot use as[String].

scala> JsObject(Seq("abc" -> JsObject(Seq("edf" -> JsString("""111\2222"""))))).toString()
val res99: String = {"abc":{"edf":"111\\2222"}}    // <-- I have no ideea how I can print single back slash here

I want to convert JsObject to a string without backslash escaping, is there a way to do this?

Upvotes: 0

Views: 841

Answers (1)

Jack Leow
Jack Leow

Reputation: 22477

"abc\edf" is not valid JSON, as per the JSON specs: https://www.json.org/json-en.html

\ can only be followed by ", \, /, b, f, n, r, t, or u+4 hexadecimal digits representing a Unicode code point.

enter image description here

Play Framework simply isn't allowing you to output malformed JSON.

More specifically, a single \ must be escaped in JSON to \\. But if you parse the JSON back into Scala, it'll get unescaped back to \.

val in = """abc\edf"""
val out = Json.parse(Json.stringify(JsString(in))).as[String]

out should look like this abc\edf.

To extract a specific property out of an object, use Play's JSON traversal mechanism.

scala> val obj = JsObject(Seq("abc" -> JsObject(Seq("edf" -> JsString("""111\2222""")))))
val obj: play.api.libs.json.JsObject = {"abc":{"edf":"111\\2222"}}

scala> (obj \ "abc" \ "edf").as[String]
val res0: String = 111\2222

Upvotes: 2

Related Questions