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

如何在Scala中使用Gson序列化列表?,scala,gson,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和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本机JSON库的其他建议?

您可以尝试使用lift JSON,它是本机Scala库:

或其他建议


该插件提供了一些scala支持,包括。

或其他建议

是Scala中轻量级、干净且高效的JSON实现

它具有以下特点:

  • JSON语言元素的简单不可变模型
  • 一个高效的JSON PEG解析器(使用parboiled实现)
  • 可以选择压缩或漂亮的JSON到字符串打印
  • 自定义对象的基于类型类(反)序列化(无反射、无入侵)

  • 您可以使用java转换器:

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

    您可以在类型适配器中使用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)
    
    case类GsonListAdapter()使用JsonDeserializer[List[\u]]扩展JsonSerializer[List[\u]]{
    导入sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
    导入scala.collection.JavaConverters_
    @抛出(类[JsonParseException])
    def反序列化(jsonElement:jsonElement,t:Type,jdc:JsonDeserializationContext):列表[\u]={
    val p=scalaListTypeToJava(t.asInstanceOf[ParameterizedType])//安全强制转换,因为列表是参数化类型。
    
    val javaList:java.util.List[;这是我决定使用的。我发现以下帖子很有用:spray json不适用于异构集合,这是一个巨大的限制。它不总是适用于某些嵌套类型,如
    List[Map[String,Int]]
    ,它将给出错误的json表示。