1. 简介
JSON(JavaScript Object Notation)作为一种轻量级的数据交换格式,广泛应用于前后端通信、微服务间数据传输等场景。作为开发者,我们经常需要从一段 JSON 字符串中提取出某个具体的字段值。
本文将介绍在 Kotlin 中提取 JSON 字符串中单个值的几种常用方式,涵盖主流库的实际用法,并对比其特点,方便你在实际项目中做出合适选择——毕竟踩过才知道哪个坑更深 😄。
2. 使用 Kotlinx Serialization 库
Kotlinx.serialization 是 JetBrains 官方推出的序列化框架,原生支持 Kotlin,无需反射,性能优秀,特别适合纯 Kotlin 项目。
2.1 Maven 和 Gradle 依赖
使用 Maven 时,在 pom.xml
中添加:
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-serialization-json-jvm</artifactId>
<version>1.6.2</version>
</dependency>
使用 Gradle(Kotlin DSL),在 build.gradle.kts
中添加:
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json-jvm:1.6.2")
✅ 提示:如果你使用的是多平台或 Android 项目,请确保引入对应平台的模块。
2.2 实现方式
通过 Json
构造函数创建一个解析器实例。虽然处理 JsonObject
时不需要配置,但建议开启 ignoreUnknownKeys = true
,避免后续扩展字段导致反序列化失败。
@Test
fun `extract values from JSON string using Kotlinx serialization`() {
val json = Json { ignoreUnknownKeys = true }
val jsonString = "{\"name\":\"John\", \"age\":30, \"city\":\"New York\"}"
val jsonObject = json.parseToJsonElement(jsonString).jsonObject
val name = jsonObject["name"]?.jsonPrimitive?.content
val city = jsonObject["city"]?.jsonPrimitive?.content
val age = jsonObject["age"]?.jsonPrimitive?.int
assertEquals("John", name)
assertEquals("New York", city)
assertEquals(30, age)
assertEquals("{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}", jsonObject.toString())
}
📌 核心步骤说明:
- ✅
parseToJsonElement()
:将字符串解析为JsonElement
- ✅
.jsonObject
:转为JsonObject
类型 - ✅
["key"]
:通过下标操作符获取对应字段的JsonPrimitive
- ✅
.content
/.int
:提取原始值(字符串或整数)
⚠️ 注意:jsonPrimitive?.content
返回的是 String 类型,即使原始是数字;若需类型转换,应使用 .int
、.double
等属性。
3. 使用 Gson 库
Gson 是 Google 推出的经典 Java JSON 库,兼容性极强,几乎成为 Android 开发的标配。它也完全适用于 Kotlin,尤其适合混合语言项目。
3.1 Maven 和 Gradle 依赖
Maven 配置:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.10.1</version>
</dependency>
Gradle(Kotlin DSL):
implementation("com.google.code.gson:gson:2.10.1")
❌ 踩坑提醒:Gson 对 Kotlin 的 data class 支持有限,特别是默认参数和不可变属性,建议仅用于简单解析场景。
3.2 实现方式
@Test
fun `extract values from JSON string using Gson`() {
val gson = Gson()
val jsonString = "{\"name\":\"John\", \"age\":30, \"city\":\"New York\"}"
val jsonObject = gson.fromJson(jsonString, JsonObject::class.java)
val name = jsonObject.get("name").asString
val city = jsonObject.get("city").asString
val age = jsonObject.get("age").asInt
assertEquals("John", name)
assertEquals("New York", city)
assertEquals(30, age)
assertEquals("{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}", jsonObject.toString())
}
📌 关键点:
- ✅
fromJson(jsonString, JsonObject::class.java)
:直接解析为JsonObject
- ✅
.get("key")
:获取JsonElement
- ✅
.asString
/.asInt
:安全地转换为目标类型
💡 小技巧:如果字段可能为空,可用 has("key")
先判断是否存在,避免 NPE。
4. 使用 Jackson 库
Jackson 是 Java 生态中最强大的 JSON 处理库之一,性能优异,功能丰富,尤其适合 Spring Boot 项目集成。
4.1 Maven 和 Gradle 依赖
Maven:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.16.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
<version>2.16.0</version>
</dependency>
⚠️ 注意:必须同时引入 jackson-databind
和 jackson-module-kotlin
才能完整支持 Kotlin 特性(如 data class、默认参数等)。
Gradle(Kotlin DSL):
implementation("com.fasterxml.jackson.core:jackson-databind:2.16.0")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.16.0")
4.2 实现方式
@Test
fun `extract values from JSON string using Jackson library`() {
val objectMapper = jacksonObjectMapper()
val jsonString = "{\"name\":\"John\", \"age\":30, \"city\":\"New York\"}"
val jsonObject = objectMapper.readValue<JsonNode>(jsonString)
val name = jsonObject.get("name").asText()
val city = jsonObject.get("city").asText()
val age = jsonObject.get("age").asInt()
assertEquals("John", name)
assertEquals("New York", city)
assertEquals(30, age)
assertEquals("{\"name\":\"John\",\"age\":30,\"city\":\"New York\"}", jsonObject.toString())
}
📌 核心流程:
- ✅
jacksonObjectMapper()
:Kotlin 扩展函数,自动配置好 Kotlin 模块 - ✅
readValue<JsonNode>()
:将字符串读取为树形结构JsonNode
- ✅
get("field")
:获取子节点 - ✅
asText()
/asInt()
:类型提取方法
✅ 优势:支持复杂嵌套结构查询,比如 jsonObject.get("user").get("address").get("zipCode")
,非常适合动态解析。
5. 总结
方案 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
✅ Kotlinx Serialization | 纯 Kotlin 项目 | 零反射、编译期生成、类型安全 | 学习成本略高,生态相对小 |
✅ Gson | Android / 老旧项目 | 简单易用、兼容性强 | 不支持 Kotlin 默认参数,性能一般 |
✅ Jackson | Spring Boot / 微服务 | 功能强大、性能好、社区活跃 | 配置稍复杂,依赖较多 |
📌 最终选择建议:
- 如果你在写一个现代 Kotlin 服务(尤其是 Ktor 或 Spring Boot + Kotlin),推荐优先使用 Kotlinx Serialization
- 若项目已重度依赖 Spring,那 Jackson 是最自然的选择
- 在 Android 上做轻量级 JSON 解析?Gson 依然够用,但注意规避 Kotlin 兼容性问题
所有示例代码均可在 GitHub 获取:https://github.com/Baeldung/kotlin-tutorials/tree/master/kotlin-json