代码之家  ›  专栏  ›  技术社区  ›  lev

Gson用基元类型反序列化scala集合

  •  0
  • lev  · 技术社区  · 7 年前

    我正在尝试使用gson反序列化scala case类,当case类包含基元类型的集合时出现问题。

    考虑以下代码:

    import com.google.gson._
    import scala.collection.JavaConverters._
    
    //custom deserialization for Seq
    class SeqDeserializer[T] extends JsonDeserializer[scala.collection.Seq[T]] {
    
      override def deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): scala.collection.Seq[T] = {
    
        //this is the `Type` of `T`
        val innerType = typeOfT.asInstanceOf[ParameterizedType].getActualTypeArguments.head //there is only one type arg since it a Seq
        println(s"json=$json, type=$innerType")
        json
          .getAsJsonArray
          .asScala
          .map(j => context.deserialize[T](j, innerType))
          .toSeq
      }
    }
    
    //initiate gson:
    val builder = new GsonBuilder().registerTypeAdapter(classOf[scala.collection.Seq[Any]], new SeqDeserializer[Any])
    val gson = builder.create()
    

    case class Top(
                  ints: Seq[Int] = Nil,
                  items: Seq[Item] = Nil
                  )
    
    case class Item(i: Int = 0)
    

    val json =
      """
        |{
        |   "ints": [1,2,3],
        |   "items": [
        |   {
        |      "i": 1
        |   },
        |   {
        |      "i": 2
        |   }
        |   ]
        |}
      """.stripMargin
    
    val res = gson.fromJson(json, classOf[Top])
    
    println(res) //1
    println(res.items.map(_.toString)) //2
    println(res.ints.map(_.toString))  //3
    

    println 将打印:

    顶部(列表(1.0、2.0、3.0)、列表(项目(1)、项目(2)))

    我们已经看到有一个问题,因为 ints 是双打吗
    第二个 将打印:

    清单(第(1)项、第(2)项)

    (如预期)
    第三天呢 打印 ,我得到一个例外:

    java.lang.ClassCastException类: java.lang.Double文件不能强制转换为 scala.runtime.box运行时.取消绑定(BoxesRunTime.java:101)

    SeqDeserializer

    json=[1,2,3],类型=类java.lang.Object对象
    json=[{“i”:1},{“i”:2}],type=class项

    Seq[Item] , gson 正确识别内部类型为 Item
    但是对于 Seq[Int] ,内部类型标识为 Object ,然后解析为 Double Int
    我猜这和拳击有关

    我该怎么做 格森 在集合中正确处理基元类型?

    0 回复  |  直到 7 年前