解析 JSON
将文本转换为 JSON 值。
解析 JSON 是 CoddyKit 上的免费 Scala for Backend Engineering & Functional Programming 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Scala for Backend Engineering & Functional Programming 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Scala for Backend Engineering & Functional Programming 课程共包含 4 节课。
为什么选择 Circe?
Circe 是 Scala 中广受欢迎的 JSON 库,构建于 cats 函数式生态之上。
它注重类型安全和不可变性:解析会返回 Either,而不是抛出异常;解码会生成有类型的值,而不是无类型的映射。
本课将介绍如何把原始 JSON 文本转换为 Circe 的 Json 模型。
添加依赖
Circe 由多个模块组成。要进行解析并使用核心模型,您需要 circe-core 和 circe-parser。
circe-generic 模块会添加编解码器的自动派生功能,后续课程将介绍这一功能。
libraryDependencies ++= Seq(
"io.circe" %% "circe-core" % "0.14.6",
"io.circe" %% "circe-parser" % "0.14.6"
)parse 函数
读取 JSON 的入口是 io.circe.parser.parse。
它接收一个 String,并返回 Either[ParsingFailure, Json]。左侧记录语法错误,右侧保存解析后的树。
import io.circe.parser._
val result = parse("{\"name\": \"Ada\", \"age\": 36}")
// result: Either[ParsingFailure, Json]处理解析失败
由于 parse 返回 Either,您可以通过模式匹配或组合器显式处理错误,而不必使用 try/catch。
ParsingFailure 包含一条人类可读的消息,用于描述语法问题。
parse("{ not valid }") match {
case Right(json) => println(json)
case Left(err) => println(s"Failed: ${err.message}")
}Json 模型
成功解析的值是一个 Json ——表示六种 JSON 类型之一的不可变树:对象、数组、字符串、数字、布尔值或 null。
您可以使用 isObject 等谓词检查它,也可以根据其结构进行折叠。
val json = parse("[1, 2, 3]").getOrElse(Json.Null)
println(json.isArray) // true
println(json.isObject) // false使用游标导航
要读取嵌套数据,请对 Json 值调用 .hcursor。HCursor 是一种拉链结构,可以帮助您在树中移动。
使用 downField 进入对象中的某个键。
val json = parse("{\"user\": {\"name\": \"Ada\"}}").toOption.get
val cursor = json.hcursor
val name = cursor.downField("user").downField("name").as[String]
// name: Either[DecodingFailure, String] = Right(Ada)使用 as 提取值
定位到目标后,.as[A] 会尝试将当前值解码为类型 A。
它返回 Either[DecodingFailure, A],因此类型不匹配会作为一个值报告,而不是抛出异常。
val json = parse("{\"age\": 36}").toOption.get
val age = json.hcursor.downField("age").as[Int]
println(age) // Right(36)parse 与 decode
如果您希望手动检查原始的 Json 树,请使用 parse。
如果您希望一步将 String 直接转换为有类型的值 A,请使用 decode[A]。它会组合解析和解码过程。
import io.circe.parser.decode
val n: Either[io.circe.Error, Int] =
decode[Int]("42")
println(n) // Right(42)可选字段
现实中的 JSON 经常缺少某些键。在进入目标字段后,游标方法 get[A] 会在字段缺失时失败,而 getOrElse 会提供默认值。
解码为 Option[A] 时,缺失字段或值为 null 的字段会被视为 None。
val json = parse("{\"name\": \"Ada\"}").toOption.get
val nick = json.hcursor.get[Option[String]]("nickname")
println(nick) // Right(None)解析数组
通过请求 List[A] 或 Vector[A],您可以将 JSON 数组直接解码为 Scala 集合。
Circe 会映射每个元素;如果任何元素的类型不正确,就会以 DecodingFailure 立即失败。
import io.circe.parser.decode
val xs = decode[List[Int]]("[1, 2, 3]")
println(xs) // Right(List(1, 2, 3))美化打印
任何 Json 值都可以使用 .noSpaces 渲染为紧凑文本,或使用 .spaces2 渲染为带缩进的文本。
这可以将解析后的数据重新转换为文本,也便于记录日志或调试。
val json = parse("{\"a\":1,\"b\":2}").toOption.get
println(json.noSpaces)
println(json.spaces2)快速检查
测试您对 Circe 解析的理解。
回顾
您已经学会将 JSON 文本转换为 Circe 的模型。parse 会产生 Either[ParsingFailure, Json];decode[A] 会直接生成有类型的值。
HCursor 使用 downField 进行导航,.as[A] 提取有类型的值。失败会作为值返回,而不是抛出异常。
常见问题解答
「解析 JSON」课时是免费的吗?
是的 — 「解析 JSON」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Scala for Backend Engineering & Functional Programming 课程的其余内容,请升级到 CoddyKit PRO。 Scala for Backend Engineering & Functional Programming 课程共包含 4 节课。
「解析 JSON」这节课中我会学到什么?
将文本转换为 JSON 值。 你通过在浏览器中直接运行的动手代码来练习 Scala for Backend Engineering & Functional Programming,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Scala for Backend Engineering & Functional Programming 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Scala for Backend Engineering & Functional Programming 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「解析 JSON」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Scala for Backend Engineering & Functional Programming 课中编写并运行代码吗?
能。每节 Scala for Backend Engineering & Functional Programming 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。