Scala中Circe解析List[TableInfo]缺失隐式Decoder编译错误
解决Circe解码List[TableInfo]的编译错误及运行时问题
编译错误原因
报错error: could not find implicit value for parameter d: io.circe.Decoder[List[TableInfo]],本质是编译器无法生成Decoder[List[TableInfo]]——因为deriveDecoder调用未明确指定类型参数,导致Decoder[TableInfo]未被正确生成。
另外,JSON中每个元素包含pocs字段,但TableInfo类未定义该字段,即使编译通过,默认解码器也会因未知字段解码失败。
修复方案(两种可选)
方案1:手动指定解码字段(无需额外依赖)
手动定义Decoder,只解析tableName和segmentName字段,自动忽略其他字段:
import io.circe.Decoder import io.circe.parser val json: String = """ { "segmements": [ { "tableName": "X", "segmentName": "XX", "pocs": [ "aa@aa.com", "bb@bb.com" ] }, { "tableName": "Y", "segmentName": "YY", "pocs": [ "aa@aa.com", "bb@bb.com" ] } ] } """ final case class TableInfo(tableName: String, segmentName: String) object TableInfo { // 手动指定要解码的字段,自动忽略其他字段 implicit final val TableInfoDecoder: Decoder[TableInfo] = Decoder.forProduct2("tableName", "segmentName")(TableInfo.apply) } val result = for { data <- parser.parse(json) obj <- data.asObject.toRight(new Exception("数据不是对象类型")) segments <- obj("segmements").toRight(new Exception("JSON缺少segmements字段")) r <- segments.as[List[TableInfo]] } yield r println(result)
方案2:使用配置忽略未知字段(需circe-generic-extras依赖)
通过配置让解码器自动忽略JSON中未定义在case类里的字段:
import io.circe.Decoder import io.circe.generic.extras.Configuration import io.circe.generic.extras.semiauto.deriveConfiguredDecoder import io.circe.parser val json: String = """ { "segmements": [ { "tableName": "X", "segmentName": "XX", "pocs": [ "aa@aa.com", "bb@bb.com" ] }, { "tableName": "Y", "segmentName": "YY", "pocs": [ "aa@aa.com", "bb@bb.com" ] } ] } """ // 全局配置:忽略未知字段 implicit val config: Configuration = Configuration.default.withIgnoreUnknownKeys final case class TableInfo(tableName: String, segmentName: String) object TableInfo { // 明确指定类型参数,确保生成正确的Decoder implicit final val TableInfoDecoder: Decoder[TableInfo] = deriveConfiguredDecoder[TableInfo] } val result = for { data <- parser.parse(json) obj <- data.asObject.toRight(new Exception("数据不是对象类型")) segments <- obj("segmements").toRight(new Exception("JSON缺少segmements字段")) r <- segments.as[List[TableInfo]] } yield r println(result)
核心修复点
- 编译错误:为
deriveDecoder/deriveConfiguredDecoder明确指定类型参数[TableInfo],让编译器正确生成Decoder[TableInfo],Circe会自动推导Decoder[List[TableInfo]] - 运行时错误:通过手动指定字段或配置忽略未知字段,解决JSON中存在case类未定义字段的问题
内容的提问来源于stack exchange,提问作者Vish0111
相关产品推荐
相关产品推荐

