如何在Scala中使用Gson序列化List?

Kev*_*vin 10 scala gson

我希望能一起使用Scala和Gson.它似乎主要工作,但当我做这样的事情时,它将列表视为一个对象,而不是一个数组:

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

我的JSON结果是这样的:

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

    }
}
Run Code Online (Sandbox Code Playgroud)

通常Gson将列表转换为数组.我确定这都是因为Gson不了解Scala的收集课程,但是我能做些什么才能使这个工作成功?或者使用Scala-native JSON库的其他建议?

ton*_*nek 10

您可以尝试提升json,它是原生的scala lib:http://www.assembla.com/spaces/liftweb/wiki/JSON_Support


dme*_*ter 7

你可以使用java转换器:

import scala.collection.JavaConverters._
case class MyType (val x:String, val y:List[SomeOtherType]) {
   def toJson() = new Gson().toJson(this.asJava())
}
Run Code Online (Sandbox Code Playgroud)


om-*_*nom 6

Or other suggestions

spray-json是Scala中一个轻量级,干净且高效的JSON实现.

它具有以下功能:

  1. JSON语言元素的简单不可变模型
  2. 一个高效的JSON PEG解析器(用parboiled实现)
  3. 可选择紧凑或漂亮的JSON到字符串打印
  4. 自定义对象的基于类型(de)的序列化(无反射,无入侵)


小智 6

您可以在类型适配器中使用 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)
Run Code Online (Sandbox Code Playgroud)