Scala类对象转JSON及依赖对象操作,指定JSON的Case Class设计
Hey,我来帮你解决这两个Scala转JSON的问题,都是日常开发里很常见的场景,咱们一步步拆解:
在Scala里,处理对象和JSON的互转,咱们一般用成熟的JSON库,比如Circe或者Play JSON,我这里以Circe为例(它的自动派生功能特别省心),给你捋清楚步骤:
第一步:添加依赖(如果用SBT的话):
在你的build.sbt里加入这些依赖:libraryDependencies ++= Seq( "io.circe" %% "circe-core" % "0.14.6", "io.circe" %% "circe-generic" % "0.14.6", "io.circe" %% "circe-parser" % "0.14.6" )第二步:定义Case Class(包括依赖的嵌套对象)
JSON里的嵌套结构,对应Scala里的嵌套Case Class,只要你把所有依赖的对象都定义成Case Class,库就能自动处理它们的转换。第三步:派生编码器/解码器
导入Circe的自动派生包,就能让库自动生成Case Class和JSON之间的转换逻辑:import io.circe.generic.auto._ import io.circe.syntax._第四步:实际转换操作
把对象转成JSON字符串,或者把JSON字符串解析成对象都很简单。举个带依赖对象的例子:// 依赖对象:地址 case class Address(street: String, city: String) // 主对象:用户,包含地址依赖 case class User(name: String, age: Int, address: Address) // 创建对象实例 val alice = User("Alice", 30, Address("Main St", "London")) // 转成紧凑的JSON字符串 val compactJson = alice.asJson.noSpaces // 转成带缩进的易读JSON val prettyJson = alice.asJson.spaces2 println(prettyJson)输出的JSON会自动包含嵌套的
address对象,完全不需要额外处理依赖对象的转换逻辑。
先把你要生成的JSON结构贴出来,方便咱们对应拆解:
{
"client": "some-client",
"target": "some-target",
"function": "some-function",
"arg": {
"doer": "machine",
"path": {
"machine": {
"application": "some-application",
"env": "some-env",
"machines": {"A": "Do something", "B": "Do more"}
}
}
}
}
咱们从外到内逐层对应设计Case Class:
- 最内层的
MachineInfo:对应JSON里path.machine的结构,里面的machines是键值对,用Scala的Map[String, String]来表示最合适。 Path类:对应arg.path,里面只有一个machine字段。Arg类:对应最外层的arg,包含doer和path两个字段。- 最外层的
MachinePayload:就是你已经开始写的类,包含client、target、function和arg。
完整的代码如下:
import io.circe.generic.auto._ import io.circe.syntax._ // 最内层:对应path.machine case class MachineInfo(application: String, env: String, machines: Map[String, String]) // 对应arg.path case class Path(machine: MachineInfo) // 对应最外层的arg case class Arg(doer: String, path: Path) // 最外层的Payload case class MachinePayload(client: String, target: String, function: String, arg: Arg)
现在你可以用这些类来生成目标JSON了:
// 逐层构建对象 val machineDetails = MachineInfo( application = "some-application", env = "some-env", machines = Map("A" -> "Do something", "B" -> "Do more") ) val path = Path(machineDetails) val arg = Arg(doer = "machine", path = path) val finalPayload = MachinePayload( client = "some-client", target = "some-target", function = "some-function", arg = arg ) // 生成带缩进的易读JSON val targetJson = finalPayload.asJson.spaces2 println(targetJson)
运行这段代码,就能得到你想要的JSON结构啦。
内容的提问来源于stack exchange,提问作者NiceOneMoney

