Scala 2.11中Jackson模块结合过滤时抛出类型转换异常求助
解决Scala中Jackson解析JSON列表后过滤抛出ClassCastException的问题
我完全懂你这种困惑——明明解析完能打印出数据,一加过滤操作就报类型转换错误,这确实挺让人摸不着头脑的。咱们来一步步拆解问题,找到解决办法:
问题根源:Java类型擦除导致泛型信息丢失
你当前用objectMapper.readValue(getData, classOf[List[Data]])来解析JSON,但由于Java的类型擦除特性,运行时JVM会丢失List[Data]里泛型参数Data的具体信息。Jackson没办法正确识别列表元素该映射到Data类,只能把每个JSON对象默认解析成HashMap(也就是你异常里看到的HashTrieMap)。
所以println(data)能输出内容,是因为HashMap的toString方法能打印数据,但当你尝试调用e.deaths时,JVM发现实际对象是HashMap而非Data,直接抛出了类型转换异常。
解决方案:用TypeReference保留泛型信息
要让Jackson正确解析带泛型的列表,你需要使用com.fasterxml.jackson.core.type.TypeReference来明确指定List[Data]的完整类型。修改解析代码如下:
import com.fasterxml.jackson.core.type.TypeReference // 替换原来的解析行 val data: List[Data] = objectMapper.readValue(getData, new TypeReference[List[Data]] {})
修改后的完整代码:
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.scala.DefaultScalaModule import com.fasterxml.jackson.core.type.TypeReference import scala.io.Source object CovidAnalytics { val objectMapper: ObjectMapper = new ObjectMapper() objectMapper.registerModule(DefaultScalaModule) def main(args: Array[String]): Unit = { val getData: String = Source.fromURL("https://api.apify.com/v2/datasets/58a4VXwBBF0HtxuQa/items?format=json&clean=1").mkString // 使用TypeReference明确泛型类型 val data: List[Data] = objectMapper.readValue(getData, new TypeReference[List[Data]] {}) println(data) val filter = data.filter(e => e.deaths != "") println(filter) } }
额外优化:处理可选字段的空值安全性
另外,你的Data类里的字段都是非Option类型(比如deaths: String),如果API返回的JSON中可能存在null值,建议把这些字段改成Option[String],避免解析时遇到空值抛出异常。比如:
case class Data( activeCases: Option[String], recovered: Option[String], deaths: Option[String], totalCases: Option[String], sourceUrl: Option[String], lastUpdatedAtApify: Option[String], readMe: Option[String], regionData: Option[List[RegionData]] )
对应的过滤操作也能写成更安全的形式:
val filter = data.filter(_.deaths.exists(_ != ""))
内容的提问来源于stack exchange,提问作者Jayant Chauhan
相关产品推荐
相关产品推荐

