如何实现Scala Case Class序列化仅输出字符串、整型及嵌套JSON字符串
可行性结论
该需求完全可以实现,核心实现逻辑为:序列化时对非顶级的嵌套Case Class字段,先执行一次完整JSON序列化得到JSON字符串,再将该字符串作为值写入顶级对象的对应字段即可。
具体实现方案(以Circe JSON库为例)
第一步:添加依赖
SBT配置中添加Circe相关依赖:
libraryDependencies ++= Seq( "io.circe" %% "circe-core" % "0.14.6", "io.circe" %% "circe-generic" % "0.14.6", "io.circe" %% "circe-parser" % "0.14.6" )
第二步:代码实现
// 导入Circe相关依赖 import io.circe._ import io.circe.generic.semiauto._ import io.circe.syntax._ // 定义示例Case Class case class Deepest(someNum: Int) case class Inner(superDeep: Deepest) case class Outer(aValue: Int, aNestedValue: Inner) // 定义基础嵌套类型的默认序列化器 implicit val deepestEncoder: Encoder[Deepest] = deriveEncoder[Deepest] implicit val innerEncoder: Encoder[Inner] = deriveEncoder[Inner] // 自定义Outer类型的序列化器,将嵌套字段转为JSON字符串值 implicit val outerEncoder: Encoder[Outer] = Encoder.instance { outer => Json.obj( "aValue" -> outer.aValue.asJson, "aNestedValue" -> Json.fromString(outer.aNestedValue.asJson.noSpaces) ) } // 封装顶级序列化方法,匹配预期的外层包结构 def serializeOuter(outer: Outer): String = { Json.obj("Outer" -> outer.asJson).noSpacesSortKeys }
第三步:测试验证
执行测试代码:
val testInstance = Outer(aValue = 5, aNestedValue = Inner(superDeep = Deepest(someNum = 10))) println(serializeOuter(testInstance))
输出结果完全匹配需求:
{ "Outer": { "aValue": 5, "aNestedValue": "{\"superDeep\":{\"someNum\":10}}" } }
扩展说明
如果使用Play JSON等其他Scala JSON库,实现思路完全一致,只需要自定义对应类型的序列化规则(Writes实现)即可。如果有大量嵌套类型需要处理,可以封装通用工具方法,自动识别非顶级嵌套类型并执行转字符串序列化,无需逐个手写自定义序列化器。
内容的提问来源于stack exchange,提问作者thisisnotabus
相关产品推荐
相关产品推荐

