Как я могу использовать Gson в Scala для сериализации списка? - PullRequest
9 голосов
/ 22 июля 2011

Я надеялся использовать Scala и Gson вместе. Кажется, что это в основном работает, но когда я делаю что-то подобное, он обрабатывает список как объект, а не как массив:

case class MyType (val x:String, val y:List[SomeOtherType]) {
    def toJson() = new Gson().toJson(this)
}

И мой JSON получается примерно так:

{
    "x":"whatever",
    "y": {

    }
}

Обычно Gson преобразует списки в массивы. Я уверен, что это все потому, что Гсон не знает о классах коллекций Scala, но есть какие-нибудь идеи о том, что я могу сделать, чтобы эта работа? Или другие предложения с использованием Scala-нативных библиотек JSON?

Ответы [ 5 ]

10 голосов
/ 22 июля 2011

Вы можете попробовать поднять JSON, это родной Scala lib: http://www.assembla.com/spaces/liftweb/wiki/JSON_Support

7 голосов
/ 07 декабря 2011

Вы можете использовать конвертер Java:

import scala.collection.JavaConverters._
case class MyType (val x:String, val y:List[SomeOtherType]) {
   def toJson() = new Gson().toJson(this.asJava())
}
6 голосов
/ 22 июля 2011

Or other suggestions

spray-json - это легкая, чистая и эффективная реализация JSON в Scala.

Имеет следующие функции:

  1. Простая неизменяемая модель элементов языка JSON
  2. Эффективный синтаксический анализатор JSON PEG (реализован с пропуском)
  3. Выбор либо компактной, либо красивой печати JSON-to-string
  4. Сериализация (де) сериализации пользовательских объектов на основе класса типов (без отражения, без вторжения)
4 голосов
/ 10 июня 2015

Вы можете использовать конвертеры Java в адаптере типов, но это немного привередливо:

  case class GsonListAdapter() extends JsonSerializer[List[_]] with JsonDeserializer[List[_]] {
    import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
    import scala.collection.JavaConverters._

    @throws(classOf[JsonParseException])
    def deserialize(jsonElement: JsonElement, t: Type, jdc: JsonDeserializationContext): List[_] = {
      val p = scalaListTypeToJava(t.asInstanceOf[ParameterizedType]) // Safe casting because List is a ParameterizedType.
      val javaList: java.util.List[_ <: Any] = jdc.deserialize(jsonElement, p)
      javaList.asScala.toList
    }

    override def serialize(obj: List[_], t: Type, jdc: JsonSerializationContext): JsonElement = {
      val p = scalaListTypeToJava(t.asInstanceOf[ParameterizedType]) // Safe casting because List is a ParameterizedType.
      jdc.serialize(obj.asInstanceOf[List[Any]].asJava, p)
    }

    private def scalaListTypeToJava(t: ParameterizedType): ParameterizedType = {
      ParameterizedTypeImpl.make(classOf[java.util.List[_]], t.getActualTypeArguments, null)
    }
  }

  val gson = new GsonBuilder().registerTypeHierarchyAdapter(classOf[List[_]], new GsonListAdapter()).create()

  val l1 = List("a", "c")
  val stringListType = new TypeToken[List[String]] {}.getType
  val json1 = gson.toJson(l1, stringListType)
  println(json1) // ["a","c"]
  val newL1: List[String] = gson.fromJson(json1, stringListType)
  assert(l1 === newL1)

  val l2 = List(1, 3)
  val intListType = new TypeToken[List[Int]] {}.getType
  val json2 = gson.toJson(l2, intListType)
  println(json2) // [1,3]
  val newL2: List[Int] = gson.fromJson(json2, intListType)
  assert(l2 === newL2)
3 голосов
/ 22 июля 2011

Или другие предложения

Дополнение Jackson jackson-module-scala обеспечивает некоторую поддержку scala, включая сериализацию списков .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...