2016-02-03 48 views
10

我有一個非常簡單的例子:如何序列化帶有UTF-8字符的json4s的JSON?

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" 
} 

我想是這樣的(完全有效的據我所知)JSON:

{ 
    "english":"serialization", 
    "japanese":"シリアライゼーション" 
} 

我現在找不到它,但我想我已經讀過JSON只需要兩個特殊的UTF-8字符的地方。

查看render的編碼,看起來Strings always get this extra double-escaping for non-ASCII characters

任何人都知道如何才能獲得有效的JSON而不會雙重轉義所有UTF-8擴展字符?這似乎是一個非常類似的問題:Why does the PHP json_encode function convert UTF-8 strings to hexadecimal entities?


更新:原來,這是一個懸而未決PR #327 json4s一個開放的問題,這是有利於PR #339關閉這反過來又合併到3.4版本分支在commit on Feb 13, 2016

+0

我不知道_json4s_,但[RFC 7159](https://tools.ietf.org/html/rfc7159)表示UTF-8是JSON的默認編碼。所以從理論上說,沒有必要(只有一種選擇)逃避日文字符。您只需要一個庫或者可以配置相應的庫。 – kriegaex

回答

6

@ 0__,目前還不清楚你想用你的賞金獲得什麼答案。原始問題中提到的錯誤已經修復,因此您可以自定義是否要對Unicode字符進行編碼。您只需要使用當前版本構建,例如用build.sbt這樣的:

name := "SO_ScalaJson4sUnicodeChars" 
version := "1.0" 
scalaVersion := "2.12.1" 
libraryDependencies += "org.json4s" %% "json4s-native" % "3.5.1" 

由於在他的評論中提到@kriegaex,UTF-8是根據RFC 7159的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":"シリアライゼーション" 
} 

然而,如果對一些兼容性原因,你需要的輸出被encdeded,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我決定編輯這個答案,合併來自我自己的一些信息並修復一些小問題。我這樣做是爲了避免冗餘。我更感興趣的是一個好的,一致的答案,而不是在賞金。我現在要刪除我的。

+0

謝謝。我認爲我和OP有同樣的問題,但是發現,問題實際上是Dispatch不會回落到UTF-8,而是當內容類型沒有指定編碼時ISO拉丁語。 –

相關問題