How can I use Gson in Scala to serialize a List?

后端 未结 5 934
感动是毒
感动是毒 2021-01-04 09:54

I was hoping to use Scala and Gson together. It seems to mostly work, but when I do something like this, it treats the list as an object, not an array:

case          


        
相关标签:
5条回答
  • 2021-01-04 10:09

    Or other suggestions

    spray-json is a lightweight, clean and efficient JSON implementation in Scala.

    It sports the following features:

    1. Simple immutable model of the JSON language elements
    2. An efficient JSON PEG parser (implemented with parboiled)
    3. Choice of either compact or pretty JSON-to-string printing
    4. Type-class based (de)serialization of custom objects (no reflection, no intrusion)
    0 讨论(0)
  • 2021-01-04 10:14

    Or other suggestions

    The Jackson add-on jackson-module-scala provides some scala support, including serialization of lists.

    0 讨论(0)
  • 2021-01-04 10:16

    You can use Java converters in a type adapter, but it's a bit finicky:

      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)
    
    0 讨论(0)
  • 2021-01-04 10:23

    You may try lift json, it's native scala lib: http://www.assembla.com/spaces/liftweb/wiki/JSON_Support

    0 讨论(0)
  • 2021-01-04 10:24

    You can use a java converter:

    import scala.collection.JavaConverters._
    case class MyType (val x:String, val y:List[SomeOtherType]) {
       def toJson() = new Gson().toJson(this.asJava())
    }
    
    0 讨论(0)
提交回复
热议问题