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

时间:2011-07-22 03:52:14

标签: scala gson

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

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

我的JSON结果是这样的:

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

    }
}

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

5 个答案:

答案 0 :(得分:10)

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

答案 1 :(得分:7)

您可以使用java转换器:

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

答案 2 :(得分:6)

Or other suggestions

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

它具有以下特点:

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

答案 3 :(得分:4)

您可以在类型适配器中使用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)

答案 4 :(得分:3)

  

或其他建议

Jackson加载项jackson-module-scala提供了一些scala支持,包括serialization of lists