如何使用带有UTF-8字符的json4s序列化JSON?

use*_*057 10 serialization json scala utf-8 json4s

我有一个非常简单的例子:

import org.json4s._
import org.json4s.native.JsonMethods._
import org.json4s.JsonDSL._

val json = ("english" -> JString("serialization")) ~ ("japanese" -> JString("??????????"))

println(pretty(render(json)))
Run Code Online (Sandbox Code Playgroud)

我得到的是:

{
  "english":"serialization",
  "japanese":"\u30b7\u30ea\u30a2\u30e9\u30a4\u30bc\u30fc\u30b7\u30e7\u30f3"
}
Run Code Online (Sandbox Code Playgroud)

我想要的是这个(完全有效的AFAIK)JSON:

{
  "english":"serialization",
  "japanese":"??????????"
}
Run Code Online (Sandbox Code Playgroud)

我现在找不到它,但我想我已经读过JSON只需要两个特殊的UTF-8字符进行转义的地方.

查看渲染代码,看起来Strings总是为非ASCII字符获得额外的双重转义.

任何人都知道如何在没有双重转义所有UTF-8扩展字符的情况下获得有效的JSON?这似乎是一个非常类似的问题:为什么PHP json_encode函数将UTF-8字符串转换为十六进制实体?


更新:事实证明这是json4s中的一个未解决的问题,有一个未决的PR#327关闭了PR#339,而PR#339又在2016年2月13日提交中合并到3.4版本分支中.

Ser*_*gGr 7

@ 0__,目前尚不清楚你想获得什么样的答案.原始问题中提到的错误已得到修复,因此您可以自定义是否要编码Unicode字符.您只需要使用当前版本进行构建,例如build.sbt:

name := "SO_ScalaJson4sUnicodeChars"
version := "1.0"
scalaVersion := "2.12.1"
libraryDependencies += "org.json4s" %% "json4s-native" % "3.5.1"
Run Code Online (Sandbox Code Playgroud)

正如@kriegaex在他的评论中提到的,根据RFC 7159,UTF-8是JSON的默认编码,因此编码并不是绝对必要的.这就是为什么默认情况下json4s不编码,就像OP请求的那样:

package so

import org.json4s.JsonDSL._
import org.json4s._
import org.json4s.native.JsonMethods._

object SOTest extends App {
  val json = ("english" -> JString("serialization")) ~ ("japanese" -> JString("??????????"))
  println(pretty(render(json)))
}
Run Code Online (Sandbox Code Playgroud)

控制台日志:

{
  "english":"serialization",
  "japanese":"??????????"
}
Run Code Online (Sandbox Code Playgroud)

但是,如果由于某些兼容性原因,您需要输出加密,json4s也支持它.如果你这样添加自己的customJsonFormats,你得到编码输出:

package so

import org.json4s.JsonDSL._
import org.json4s._
import org.json4s.native.JsonMethods._

object SOTest extends App {
  val json = ("english" -> JString("serialization")) ~ ("japanese" -> JString("??????????"))
  implicit val customJsonFormats = new DefaultFormats {
    override def alwaysEscapeUnicode: Boolean = true
  }
  println(pretty(render(json)))
}
Run Code Online (Sandbox Code Playgroud)

控制台日志:

{
  "english":"serialization",
  "japanese":"\u30b7\u30ea\u30a2\u30e9\u30a4\u30bc\u30fc\u30b7\u30e7\u30f3"
}
Run Code Online (Sandbox Code Playgroud)

@kriegaex更新:我决定编辑这个答案,合并我自己的一些信息并解决一些小问题.我这样做是为了避免冗余.我对一个好的,一致的答案比在赏金中更感兴趣.我现在要删除我的.