2016-02-03 18 views
10

Tôi có một ví dụ thực sự đơn giản:Làm thế nào để tuần tự hóa JSON với json4 với các ký tự UTF-8?

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

val json = ("english" -> JString("serialization")) ~ ("japanese" -> JString("シリアライゼーション")) 

println(pretty(render(json))) 

Những gì tôi có được ra khỏi đó là:

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

:

{ 
    "english":"serialization", 
    "japanese":"\u30b7\u30ea\u30a2\u30e9\u30a4\u30bc\u30fc\u30b7\u30e7\u30f3" 
} 

Những gì tôi muốn điều này (hoàn toàn hợp lệ AFAIK) JSON là Tôi không thể tìm thấy nó ngay bây giờ, nhưng tôi nghĩ rằng tôi đã đọc ở đâu đó rằng JSON chỉ yêu cầu hai ký tự UTF-8 đặc biệt để được thoát.

Nhìn vào mã cho render, có vẻ như Strings always get this extra double-escaping for non-ASCII characters.

Bất cứ ai cũng biết cách tôi có thể nhận được JSON hợp lệ mà không cần phải thoát hai lần tất cả các ký tự mở rộng UTF-8? Điều này có vẻ như một vấn đề rất tương tự như: Why does the PHP json_encode function convert UTF-8 strings to hexadecimal entities?


Cập nhật: Hóa ra đây là một vấn đề mở trong json4s với một cấp phát PR #327 được đóng ủng hộ PR #339 do đó sáp nhập vào phiên bản 3.4 chi nhánh trong một số commit on Feb 13, 2016.

+0

Tôi không biết về _json4s_, nhưng [RFC 7159] (https://tools.ietf.org/html/rfc7159) nói rằng UTF-8 là mã hóa mặc định cho JSON.Vì vậy, về mặt lý thuyết không cần thiết (chỉ có một lựa chọn) để thoát khỏi các ký tự Nhật Bản. Bạn chỉ cần một thư viện mà nó hoặc có thể được cấu hình cho phù hợp. – kriegaex

Trả lời

6

@ 0__, không rõ câu trả lời bạn muốn nhận được với tiền thưởng của mình. Lỗi được đề cập trong câu hỏi ban đầu đã được sửa, vì vậy bạn có thể tùy chỉnh xem bạn có muốn mã hóa các ký tự Unicode hay không. Bạn chỉ cần xây dựng với phiên bản hiện tại, ví dụ: với một build.sbt như thế này:

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

Như @kriegaex nêu trong bình luận của ông, UTF-8 là bảng mã mặc định cho JSON theo RFC 7159, do đó mã hóa là không thực sự cần thiết. Đây là lý do tại sao bởi mặc định json4s không mã hóa, cũng giống như OP yêu cầu:

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

điều khiển đăng nhập:

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

Tuy nhiên, nếu vì một lý do tương thích bạn cần đầu ra được encdeded, json4s cũng hỗ trợ điều đó. Nếu bạn thêm đầu ra riêng customJsonFormats như thế này, bạn nhận được mã hóa của bạn:

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

điều khiển đăng nhập:

{ 
    "english":"serialization", 
    "japanese":"\u30b7\u30ea\u30a2\u30e9\u30a4\u30bc\u30fc\u30b7\u30e7\u30f3" 
} 

Update bằng cách @kriegaex: tôi quyết định chỉnh sửa câu trả lời này, hợp nhất trong một số thông tin từ của riêng tôi và sửa một vài vấn đề nhỏ. Tôi đã làm điều này để tránh dư thừa. Tôi quan tâm nhiều hơn đến một câu trả lời tốt, nhất quán hơn trong tiền thưởng. Tôi sẽ xóa của tôi ngay bây giờ.

+0

Cảm ơn. Tôi nghĩ rằng tôi đã có cùng một vấn đề như OP, nhưng phát hiện ra, vấn đề đã được thực sự Dispatch không rơi trở lại UTF-8 nhưng ISO Latin khi nội dung kiểu không chỉ định mã hóa. –

Các vấn đề liên quan