使用io.circe编码Map为JSON时遇隐式Encoder缺失问题求助
解决io.circe编码Scala Map为JSON的问题
问题原因
你遇到的错误源于Map的值类型被编译器推断为java.io.Serializable——因为Map中同时包含String和Json两种类型的值,它们的共同父类是Serializable。而circe默认不为Serializable类型提供编码器,即便导入io.circe.generic.auto._也无法处理这种非类型安全的混合值Map。
推荐解决方案
方案1:使用Case Class(类型安全,推荐)
既然目标JSON结构固定,定义对应的Case Class是最规范的做法,circe的泛型编码器可直接处理:
import io.circe._ import io.circe.generic.auto._ import io.circe.syntax._ // 定义与目标JSON匹配的Case Class case class Output( key: String, message: String, payload: Json ) // 构建实例并编码为JSON val output = Output( root.key.string.getOption(data).getOrElse(""), root.message.string.getOption(data).getOrElse(""), root.payload.json.getOption(data).getOrElse(Json.Null) ) val targetJson = output.asJson
方案2:直接构建Json对象(无需Map)
跳过Map,直接用circe的Json.obj方法构造目标JSON,避免类型推断问题:
import io.circe._ import io.circe.syntax._ val targetJson = Json.obj( "key" -> Json.fromString(root.key.string.getOption(data).getOrElse("")), "message" -> Json.fromString(root.message.string.getOption(data).getOrElse("")), "payload" -> root.payload.json.getOption(data).getOrElse(Json.Null) )
方案3:统一Map的值类型为Json(若必须用Map)
如果一定要使用Map,先将所有值转为Json类型,再转换为Json对象:
import io.circe._ import io.circe.syntax._ val jsonMap: Map[String, Json] = Map( "key" -> Json.fromString(root.key.string.getOption(data).getOrElse("")), "message" -> Json.fromString(root.message.string.getOption(data).getOrElse("")), "payload" -> root.payload.json.getOption(data).getOrElse(Json.Null) ) val targetJson = Json.obj(jsonMap.toSeq: _*)
内容的提问来源于stack exchange,提问作者sharingiscaring
相关产品推荐
相关产品推荐

