我将尝试准确推断您在做什么。您正在使用 Spray,所以我推测您正在使用它的 json 库“spray-json”
所以我想你有一些实例spray.json.JsObject
,并且你在问题中发布的是你在打印这个实例时得到的输出。您的 json 对象是正确的,该name
字段的值没有嵌入转义,它实际上是转义为字符串的一些 unicode 字符。
请参阅此处的定义printString
:
https ://github.com/spray/spray-json/blob/master/src/main/scala/spray/json/JsonPrinter.scala
我还将假设当您尝试使用 时unescapeJava
,您将其应用于name
字段的值,创建一个新spray.json.JsObject
实例,然后像以前一样打印该实例。鉴于您的 json 对象实际上没有任何转义,这绝对没有任何作用,然后在打印它时,打印机会像以前一样进行转义,然后您又回到了原点。
作为旁注,值得一提的是,json 规范并没有规定字符的编码方式:它们可以存储为文字值,也可以存储为 unicode 转义。例如,字符串"abc"
可以描述为 just"abc"
或 as "\u0061\u0062\u0063"
。任何一种形式都是正确的。恰好 spray-json 的作者决定对所有非 ascii 字符使用后一种形式。
所以现在你问,我能做些什么来解决这个问题?您可以要求 spray-json 作者添加一个选项,让您指定您不希望任何 unicode 转义。但我想你现在想要一个解决方案。
最简单的做法是将对象转换为字符串(通过JsValue.toString
orJsValue.compactPrint
或JsValue.prettyPrint
),然后将结果传递给unescapeJava
. 至少这会让你回到你的西里尔原始字符。但这有点粗俗,实际上非常危险,因为某些字符在字符串文字中转义是不安全的。例如:\n
将不转义为实际返回,并且\u0022
将不转义为"
. 您可以轻松查看它将如何破坏您的 json 文档。但至少它可以证实我的理论(请记住,我一直在假设你到底在做什么)。
现在进行适当的修复:您可以简单地扩展JsonPrinter
并覆盖其printString
方法以删除 unicode 转义。像这样的东西(未经测试):
trait NoUnicodeEscJsonPrinter extends JsonPrinter {
override protected def printString(s: String, sb: StringBuilder) {
@tailrec
def printEscaped(s: String, ix: Int) {
if (ix < s.length) {
s.charAt(ix) match {
case '"' => sb.append("\\\"")
case '\\' => sb.append("\\\\")
case x if 0x20 <= x && x < 0x7F => sb.append(x)
case '\b' => sb.append("\\b")
case '\f' => sb.append("\\f")
case '\n' => sb.append("\\n")
case '\r' => sb.append("\\r")
case '\t' => sb.append("\\t")
case x => sb.append(x)
}
printEscaped(s, ix + 1)
}
}
sb.append('"')
printEscaped(s, 0)
sb.append('"')
}
}
trait NoUnicodeEscPrettyPrinter extends PrettyPrinter with NoUnicodeEscJsonPrinter
object NoUnicodeEscPrettyPrinter extends NoUnicodeEscPrettyPrinter
trait NoUnicodeEscCompactPrinter extends CompactPrinter with NoUnicodeEscJsonPrinter
object NoUnicodeEscCompactPrinter extends NoUnicodeEscCompactPrinter
然后你可以这样做:
val json: JsValue = ...
val jsonString: String = NoUnicodeEscPrettyPrinter( json )
jsonString
将以漂亮的打印格式包含您的 json 文档,并且没有任何 unicde 转义。