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

Scala 3中如何使用jsoniter序列化Map[String, Any]

解决Scala 3下jsoniter序列化Map[String, Any]的方案

一、自定义JsonValueCodec[Any]实现

jsoniter依赖明确的类型编解码器,Any本身没有默认实现,但你提到所有实际子类型(String、Int、Date等)都有可用的given编解码器,因此可以通过模式匹配+调用对应类型编解码器实现JsonValueCodec[Any]:

import com.github.plokhotnyuk.jsoniter_scala.core._
import java.util.Date

// 为Any类型实现自定义编解码器
given JsonValueCodec[Any] with {
  override def encodeValue(x: Any, out: JsonWriter): Unit = x match {
    case s: String => summon[JsonValueCodec[String]].encodeValue(s, out)
    case i: Int => summon[JsonValueCodec[Int]].encodeValue(i, out)
    case d: Date => summon[JsonValueCodec[Date]].encodeValue(d, out)
    // 按需添加需要支持的其他类型
    case other => throw new IllegalArgumentException(s"Unsupported type: ${other.getClass.getName}")
  }

  override def decodeValue(in: JsonReader, default: Any): Any = {
    // 反序列化时根据JSON token类型匹配对应编解码器
    in.peekToken() match {
      case JsonToken.STRING => summon[JsonValueCodec[String]].decodeValue(in, default.asInstanceOf[String])
      case JsonToken.NUMBER => 
        val numStr = in.readNumberAsString()
        numStr.toIntOption.getOrElse(numStr.toLong) // 示例简化,可按需扩展支持更多数值类型
      case JsonToken.DATE => summon[JsonValueCodec[Date]].decodeValue(in, default.asInstanceOf[Date])
      case _ => default
    }
  }

  override def nullValue: Any = null
}

实现后,Map[String, Any]的编解码器会自动合成,直接使用即可:

val testMap: Map[String, Any] = Map(
  "name" -> "Alice",
  "age" -> 30,
  "joinDate" -> new Date()
)

val json = writeToString(testMap)
println(json)

二、替代JSON库推荐

如果觉得自定义编解码器繁琐,以下Scala 3友好的库可以更便捷处理Map[String, Any]:

1. uPickle

轻量无依赖,原生支持动态类型结构,无需额外配置:

import upickle.default._

val testMap: Map[String, Any] = Map("a" -> 1, "b" -> "test", "c" -> true)
val json = write(testMap)
val parsedMap = read[Map[String, Any]](json)

2. Circe

通过Json中间类型处理动态结构,功能强大:

import io.circe._
import io.circe.syntax._

val testMap: Map[String, Any] = Map("x" -> 100, "y" -> "hello")
// 序列化为Json
val json: Json = testMap.mapValues {
  case s: String => Json.fromString(s)
  case i: Int => Json.fromInt(i)
  // 按需扩展其他类型转换
}.asJson

// 反序列化为Map
val parsedMap = parse(json.noSpaces)
  .right.get
  .asObject
  .map(_.toMap.mapValues(_.as[Any].right.get))
  .getOrElse(Map.empty)

3. Play JSON

可独立使用,自动处理常见基础类型:

import play.api.libs.json._

val testMap: Map[String, Any] = Map("foo" -> "bar", "baz" -> 42)
val json: JsValue = Json.toJson(testMap)
val parsedMap = Json.fromJson[Map[String, Any]](json).get

内容的提问来源于stack exchange,提问作者david.perez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 10:52:18