1. 概述
Google Gson 是处理 JSON 数据最流行的 Java 库之一,也广泛用于 Kotlin 项目中。它提供了简单而强大的 API,用于将对象序列化为 JSON 字符串,或将 JSON 字符串反序列化为对象。
本文将介绍如何使用 Gson 在 Kotlin 中处理 JSON 数组的序列化与反序列化,包括处理字段名不一致、字段缺失等常见场景。
2. Google Gson 简介
在 Gson 的语境中:
- 序列化(Serialization):将 Kotlin 对象转换为 JSON 字符串。
- 反序列化(Deserialization):将 JSON 字符串解析为 Kotlin 对象。
Gson 提供了对 Kotlin 数据类的良好支持,尤其在处理复杂嵌套结构(如 List、Map 等)时非常方便。
2.1. Maven 依赖
在使用 Gson 之前,需要在 pom.xml
中添加以下依赖:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.8</version>
</dependency>
3. 实战示例
我们以作者(Author)和文章(Article)为例,演示如何使用 Gson 解析包含嵌套数组的 JSON 数据。
先定义两个数据类:
data class Article(
var title: String,
var category: String,
var views: Int
)
data class Author(
var name: String,
var type: String? = null,
var articles: List<Article>? = null
)
3.1. 序列化数组
Gson 可以自动将 Kotlin 的 List 转换为 JSON 数组:
@Test
fun serializeObjectListTest() {
val authors = listOf(
Author("John", "Technical Author"),
Author("Jane", "Technical Author"),
Author("William", "Technical Editor")
)
val serialized = Gson().toJson(authors)
val json =
"""[{"name":"John","type":"Technical Author"},{"name":"Jane","type":"Technical Author"},{"name":"William","type":"Technical Editor"}]"""
assertEquals(serialized, json)
}
如果字段名和 JSON Key 不一致,可以使用 @SerializedName
注解指定:
data class Author(
var name: String,
var type: String? = null,
@SerializedName("author_articles")
var articles: List<Article>? = null
)
这样序列化时,字段名就会变成 author_articles
。
示例:
@Test
fun serializeObjectListWithNonMatchingKeysTest() {
val authors = listOf(
Author(
"John",
"Technical Author",
listOf(Article("Streams in Java", "Java", 3), Article("Lambda Expressions", "Java", 5))
),
Author("Jane", "Technical Author", listOf(Article("Functional Interfaces", "Java", 2))),
Author("William", "Technical Editor")
)
val serialized = Gson().toJson(authors)
val json =
"""[{"name":"John","type":"Technical Author","author_articles":[{"title":"Streams in Java","category":"Java","views":3},{"title":"Lambda Expressions","category":"Java","views":5}]},{"name":"Jane","type":"Technical Author","author_articles":[{"title":"Functional Interfaces","category":"Java","views":2}]},{"name":"William","type":"Technical Editor"}]"""
assertEquals(serialized, json)
}
3.2. 反序列化数组
反序列化 JSON 数组时,需要使用 TypeToken
来指定泛型类型:
@Test
fun deserializeObjectListTest() {
val json =
"""[{"name":"John","type":"Technical Author"},{"name":"Jane","type":"Technical Author"},{"name":"William","type":"Technical Editor"}]"""
val typeToken = object : TypeToken<List<Author>>() {}.type
val authors = Gson().fromJson<List<Author>>(json, typeToken)
assertThat(authors).isNotEmpty
assertThat(authors).hasSize(3)
assertThat(authors).anyMatch { a -> a.name == "John" }
assertThat(authors).anyMatch { a -> a.type == "Technical Editor" }
}
⚠️ 注意:Gson 默认会将缺失字段设为 null
,即使 Kotlin 数据类中该字段有默认值也是如此。例如:
@Test
fun deserializeObjectListWithMissingFieldsTest() {
val json =
"""[{"name":"John"},{"name":"Jane"},{"name":"William"}]"""
val typeToken = object : TypeToken<List<Author>>() {}.type
val authors = Gson().fromJson<List<Author>>(json, typeToken)
assertThat(authors).isNotEmpty
assertThat(authors).hasSize(3)
assertThat(authors).anyMatch { a -> a.name == "John" }
assertThat(authors).allMatch { a -> a.type == null }
}
✅ 踩坑提醒:如果你期望某些字段即使在 JSON 中不存在也保留默认值,请使用 @Expose
注解并配置 GsonBuilder
。
4. 总结
本文介绍了如何使用 Gson 在 Kotlin 中处理 JSON 数组的序列化与反序列化,包括:
- 使用
TypeToken
反序列化泛型数组 - 使用
@SerializedName
映射不同字段名 - 处理字段缺失的情况
Gson 是一个轻量且功能强大的 JSON 工具库,适合大多数 Kotlin 项目中的 JSON 处理需求。
完整示例代码请访问:GitHub 项目地址