You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 17:30:56