Gson转换嵌套List异常问题求助(Scala/Java通用)
解决Gson序列化Scala嵌套List为空对象的问题
这个问题我之前也碰到过!核心原因是Gson原生只适配Java的标准集合类型(比如java.util.List),而Scala的scala.collection.List是语言专属的集合实现,Gson没有内置对应的序列化适配器,所以处理嵌套Scala List时会识别失败,最终输出空对象{}。
下面给你几个实用的解决方案,按推荐度排序:
1. 使用Gson的Scala专用扩展库(最省心)
专门的gson-scala库已经为Scala的case类、集合等类型做了完整适配,不用自己写适配器。
首先引入依赖(以SBT为例):
libraryDependencies += "com.github.seratch" %% "gson-scala-core" % "2.10.0" // 同时确保基础Gson依赖存在 libraryDependencies += "com.google.code.gson" % "gson" % "2.10.1"
然后修改你的代码,用Scala专属的Gson实例:
import com.github.seratch.gsonscala.GsonScala case class Candy(name: String, price: Double) case class PersonCandy(name: String, age: Int, candyList: List[Candy]) val candies = List(Candy("M&M's", 1.99), Candy("Snickers", 1.59), Candy("Butterfinger", 2.33)) val personC = PersonCandy("Mark", 19, candies) // 使用Scala适配的Gson实例 val gson = GsonScala.default val pollAsJson = gson.toJson(personC) // 输出结果会是正确的嵌套数组:{"name":"Mark","age":19,"candyList":[{"name":"M&M's","price":1.99},...]}
这个方案不仅能解决List的问题,对Scala的其他集合(比如Set、Map)和case类的序列化都能完美支持。
2. 手动注册Scala List的TypeAdapter
如果不想引入额外库,可以自己写一个TypeAdapter,告诉Gson怎么处理Scala List:
import com.google.gson._ import scala.collection.JavaConverters._ // 实现Scala List的序列化/反序列化适配器 class ScalaListTypeAdapter extends TypeAdapter[List[_]] { override def write(out: JsonWriter, value: List[_]): Unit = { val gson = new Gson() out.beginArray() // 逐个序列化List中的元素 value.foreach(item => gson.toJson(item, out)) out.endArray() } override def read(in: JsonReader): List[_] = { // 反序列化时把Java List转成Scala List val javaList = new Gson().fromJson[java.util.List[_]](in, classOf[java.util.List[_]]) javaList.asScala.toList } } // 创建Gson时注册适配器 val gson = new GsonBuilder() .registerTypeHierarchyAdapter(classOf[List[_]], new ScalaListTypeAdapter()) .create() // 之后正常序列化即可 val pollAsJson = gson.toJson(personC)
3. 临时转换为Java List(快速 workaround)
如果只是临时解决单个场景,可以把Scala List转换成Java List再序列化:
import scala.collection.JavaConverters._ // 把Scala List转成Java List val personC = PersonCandy("Mark", 19, candies.asJava) val pollAsJson = new Gson().toJson(personC) // 反序列化时再转回来 val parsedPerson = gson.fromJson(pollAsJson, classOf[PersonCandy]) val scalaCandies = parsedPerson.candyList.asScala.toList
这个方法适合快速测试,但如果项目中有大量Scala集合需要序列化,还是推荐前两种方案。
内容的提问来源于stack exchange,提问作者NateH06
相关产品推荐
相关产品推荐

