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
相关产品推荐
相关产品推荐

