Подтвердить что ты не робот

Как сериализовать JSON с json4s с символами 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)))

Из чего я получаю:

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

То, что я хочу, это (совершенно правильный AFAIK) JSON:

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

Я не могу найти его сейчас, но я думаю, что где-то читал, что JSON требует только двух специальных символов UTF-8.

Рассматривая код render, кажется, что Строки всегда получайте это дополнительное двойное экранирование для символов, отличных от ASCII.

Кто-нибудь знает, как я могу получить действительный JSON без двойного экранирования всех расширенных символов UTF-8? Это похоже на очень похожую проблему: Почему функция json_encode PHP преобразует строки UTF-8 в шестнадцатеричные сущности?


Обновление. Оказывается, это открытая проблема в json4s с ожидающим PR # 327, который был закрыт в пользу PR # 339, который, в свою очередь, слился с веткой релиза 3.4 в совершить 13 февраля 2016 года.

4b9b3361

Ответ 1

@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 является кодировкой по умолчанию для JSON в соответствии с RFC 7159, поэтому кодировка не является строго необходимой. Вот почему по умолчанию 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: Я решил отредактировать этот ответ, объединив некоторую информацию из моей собственной и установив несколько мелких проблем. Я сделал это, чтобы избежать избыточности. Меня больше интересует хороший, последовательный ответ, чем в щедрости. Я сейчас удалю мою.