我有一堆文件在Apache Lucene中保留了俄语中的一些名字,当我试图将它们打印出来时,它看起来像"\u0410\u0441\u043f\u0430\u0440"
,但不是西里尔符号。该项目在Scala。我试图用Apache Commons unescapeJava
方法修复此问题,但它没有帮助。还有其他选择吗?
更新 使用Spray框架编写Project并像这样返回json。
{
"id" : 0,
"name" : "\u0410\u0441\u043f\u0430\u0440"
}
答案 0 :(得分:8)
我将尝试准确推断出你在做什么。 你正在使用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"
可以仅描述为"abc"
,或描述为"\u0061\u0062\u0063"
。两种形式都是正确的。碰巧喷涂json的作者决定将后一种形式用于所有非ascii字符。
所以现在你问,我该怎么做才能解决这个问题?您可以要求spray-json作者添加一个选项,让您指定不需要任何unicode转义。 但我想你现在想要一个解决方案 。
最简单的方法是将对象转换为字符串(通过JsValue.toString
或JsValue.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转义。
答案 1 :(得分:0)
此问题似乎已在spray-json 1.3.2中得到纠正:https://github.com/spray/spray-json/issues/46
我使用Akka HTTP 1.0遇到类似的阿拉伯字符问题,这取决于1.3.1。通过升级到1.3.2,我的问题得到了解决。