如何使用带有 UTF-8 字符的 json4s 序列化 JSON?
Posted
技术标签:
【中文标题】如何使用带有 UTF-8 字符的 json4s 序列化 JSON?【英文标题】:How to serialize JSON with json4s with UTF-8 characters? 【发布时间】:2016-05-12 03:25:18 【问题描述】:我有一个非常简单的例子:
import org.json4s._
import org.json4s.native.JsonMethods._
import org.json4s.JsonDSL._
val json = ("english" -> JString("serialization")) ~ ("japanese" -> JString("シリアライゼーション"))
println(pretty(render(json)))
我从中得到的是:
"english":"serialization",
"japanese":"\u30b7\u30ea\u30a2\u30e9\u30a4\u30bc\u30fc\u30b7\u30e7\u30f3"
我想要的是这个(完全有效的 AFAIK)JSON:
"english":"serialization",
"japanese":"シリアライゼーション"
我现在找不到它,但我想我在某处读到 JSON 只需要转义两个特殊的 UTF-8 字符。
查看render 的代码,似乎是Strings always get this extra double-escaping for non-ASCII characters。
任何人都知道如何在不双重转义所有 UTF-8 扩展字符的情况下获得有效的 JSON 吗?这似乎与以下问题非常相似:Why does the php json_encode function convert UTF-8 strings to hexadecimal entities?
更新:事实证明,这是 json4s 中的一个未解决问题,带有待处理的 PR #327,该问题已被关闭以支持 PR #339,而 PR #339 又合并到 @987654326 中的 3.4 发布分支@。
【问题讨论】:
我不知道 json4s,但是RFC 7159 说 UTF-8 是 JSON 的默认编码。所以理论上没有必要(只有一个选项)来转义日文字符。您只需要一个可以执行此操作或可以进行相应配置的库。 【参考方案1】:@0__,目前尚不清楚你想用你的赏金得到什么答案。原始问题中提到的错误已经修复,因此您可以自定义是否要对 Unicode 字符进行编码。您只需要使用当前版本进行构建,例如像这样的build.sbt
:
name := "SO_ScalaJson4sUnicodeChars"
version := "1.0"
scalaVersion := "2.12.1"
libraryDependencies += "org.json4s" %% "json4s-native" % "3.5.1"
正如 @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)))
控制台日志:
"english":"serialization",
"japanese":"シリアライゼーション"
但是,如果出于某种兼容性原因您需要对输出进行编码,那么 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)))
控制台日志:
"english":"serialization",
"japanese":"\u30b7\u30ea\u30a2\u30e9\u30a4\u30bc\u30fc\u30b7\u30e7\u30f3"
更新由 @kriegaex: 我决定编辑这个答案,合并我自己的一些信息并修复一些小问题。我这样做是为了避免冗余。我对一个好的、一致的答案比对赏金更感兴趣。我现在要删除我的。
【讨论】:
谢谢。我以为我和 OP 有同样的问题,但发现问题实际上是 Dispatch 没有回退到 UTF-8 而是 ISO Latin 当内容类型没有指定编码时。以上是关于如何使用带有 UTF-8 字符的 json4s 序列化 JSON?的主要内容,如果未能解决你的问题,请参考以下文章