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

Scala将无固定Schema JSON转为ListMap并保留全量键插入顺序的问题

Scala固定两层JSON转有序ListMap解决方案

前置说明

当前场景明确JSON仅两层嵌套,且需要保留所有层级键的原始顺序,以下两种方案均可满足需求:


方案1:配置Jackson默认Map实现(低代码,无需手动类型判断)

通过配置Jackson的Scala模块,指定所有JSON对象反序列化时默认使用ListMap实现,无需手动处理类型推断,内外层键顺序均可完全保留。

代码示例

// 导入依赖
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.module.scala.DefaultScalaModule
import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper
import com.fasterxml.jackson.databind.ObjectMapper
import scala.collection.immutable.ListMap

// 初始化并配置Mapper
val mapper = new ObjectMapper() with ScalaObjectMapper
// 注册Scala模块,指定Map默认用ListMap实现
mapper.registerModule(DefaultScalaModule.copy(mapFactory = ListMap.mapFactory))
// 禁用Map键自动排序,完全对齐原始JSON顺序
mapper.disable(DeserializationFeature.ORDER_MAP_ENTRIES_BY_KEYS)

// 原始JSON字符串
val originalJSONString = """
{
    "outerKey1": "",
    "outerKey2": "",
    "outerKey3": {
        "innerKey1": "",
        "innerKey2": "",
        "innerKey3": ""
    }
}
"""

// 直接反序列化,值类型自动适配:字符串为String,嵌套对象为ListMap
val jsonListMap = mapper.readValue[ListMap[String, Any]](originalJSONString)

// 序列化输出,键顺序和原始JSON完全一致
println(mapper.writeValueAsString(jsonListMap))

方案2:Either强类型适配(更安全,避免运行时类型转换异常)

因为JSON结构固定为两层,外层值仅可能是字符串或字符串映射,使用Either类型可以在编译期约束结构,无需运行时强转,使用更安全。

代码示例

import com.fasterxml.jackson.core.`type`.TypeReference

// 定义两层结构的TypeReference
val twoLevelMapType = new TypeReference[ListMap[String, Either[String, ListMap[String, String]]]] {}

// 反序列化
val jsonListMap = mapper.readValue(originalJSONString, twoLevelMapType)

// 使用时通过模式匹配判断值类型,无类型转换风险
jsonListMap.foreach { case (outerKey, value) =>
  value match {
    case Left(strValue) => println(s"键$outerKey为字符串类型,值:$strValue")
    case Right(innerMap) => println(s"键$outerKey为嵌套映射,内层键顺序:${innerMap.keys.mkString(",")}")
  }
}

扩展说明

如果后续需要支持任意层级的嵌套JSON,可以通过定义代数数据类型(ADT)配合自定义反序列化器实现,示例结构如下:

sealed trait OrderedJsonValue
case class StrValue(value: String) extends OrderedJsonValue
case class MapValue(value: ListMap[String, OrderedJsonValue]) extends OrderedJsonValue

这种基于类型特征匹配的方案可复用至所有半结构化数据处理场景,无需预定义全量Schema即可保留结构信息与顺序。

内容的提问来源于stack exchange,提问作者NMcD

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 17:24:06