1. 概述
Klaxon 是一个用于在 Kotlin 中解析 JSON 的开源库,支持多种操作 JSON 的方式,功能强大且使用简单。
在本文中,我们将重点介绍 Klaxon 的主要功能和使用方法,帮助你快速上手并灵活运用在项目中。
2. Maven 依赖
如果你使用的是 Maven 项目,首先需要添加 Klaxon 的依赖:
<dependency>
<groupId>com.beust</groupId>
<artifactId>klaxon</artifactId>
<version>5.6</version>
</dependency>
你可以在 mvnrepository.com 上查看最新版本。
3. API 功能概览
Klaxon 提供了四种主要的 API 来处理 JSON 文档:
- Object Binding API:将 JSON 映射为 Kotlin 对象,或反之
- Streaming API:适用于处理大体积 JSON 数据流
- JSON Path Query API:通过 JSON Path 表达式定位 JSON 中的特定字段
- Low-Level API:以 Map/List 的方式操作 JSON 数据
下面我们将逐一介绍这些 API 的使用方式。
4. Object Binding API
Object Binding 是最常用的 JSON 操作方式,可以轻松地将 JSON 字符串与 Kotlin 对象之间进行序列化和反序列化。
✅ 示例
我们先定义一个 JSON 字符串:
{
"name": "HDD"
}
然后定义一个对应的 Kotlin 类:
class Product(val name: String)
接着测试序列化:
@Test
fun givenProduct_whenSerialize_thenGetJsonString() {
val product = Product("HDD")
val result = Klaxon().toJsonString(product)
assertThat(result).isEqualTo("""{"name" : "HDD"}""")
}
再测试反序列化:
@Test
fun givenJsonString_whenDeserialize_thenGetProduct() {
val result = Klaxon().parse<Product>(
"""
{
"name" : "RAM"
}
""")
assertThat(result?.name).isEqualTo("RAM")
}
✅ 使用注解自定义映射
你可以使用 @Json
注解来自定义字段映射规则:
class CustomProduct(
@Json(name = "productName")
val name: String,
@Json(ignored = true)
val id: Int)
测试:
@Test
fun givenCustomProduct_whenSerialize_thenGetJsonString() {
val product = CustomProduct("HDD", 1)
val result = Klaxon().toJsonString(product)
assertThat(result).isEqualTo("""{"productName" : "HDD"}""")
}
可以看到:
name
被序列化为productName
id
被忽略
5. Streaming API
当处理非常大的 JSON 文件时,使用 Streaming API 可以避免一次性加载整个文档,节省内存。
✅ 示例
我们定义一个数据类:
data class ProductData(val name: String, val capacityInGb: Int)
然后使用 JsonReader
流式读取数组:
@Test
fun givenJsonArray_whenStreaming_thenGetProductArray() {
val jsonArray = """
[
{ "name" : "HDD", "capacityInGb" : 512 },
{ "name" : "RAM", "capacityInGb" : 16 }
]"""
val expectedArray = arrayListOf(
ProductData("HDD", 512),
ProductData("RAM", 16))
val klaxon = Klaxon()
val productArray = arrayListOf<ProductData>()
JsonReader(StringReader(jsonArray)).use { reader ->
reader.beginArray {
while (reader.hasNext()) {
val product = klaxon.parse<ProductData>(reader)
productArray.add(product!!)
}
}
}
assertThat(productArray).hasSize(2).isEqualTo(expectedArray)
}
💡 踩坑提醒:记得在 use
中使用 JsonReader
,避免资源泄漏。
6. JSON Path Query API
Klaxon 支持 JSON Path 查询,可以用于定位 JSON 中的特定字段。
✅ 示例
我们定义一个 JSON:
{
"inventory" : {
"disks" : [
{
"type" : "HDD",
"sizeInGb" : 1000
},
{
"type" : "SDD",
"sizeInGb" : 512
}
]
}
}
然后实现 PathMatcher
接口来匹配路径:
val pathMatcher = object : PathMatcher {
override fun pathMatches(path: String)
= Pattern.matches(".*inventory.*disks.*type.*", path)
override fun onMatch(path: String, value: Any) {
when (path) {
"$.inventory.disks[0].type"
-> assertThat(value).isEqualTo("HDD")
"$.inventory.disks[1].type"
-> assertThat(value).isEqualTo("SDD")
}
}
}
最后执行解析:
@Test
fun givenDiskInventory_whenRegexMatches_thenGetTypes() {
val jsonString = """..."""
val pathMatcher = //...
Klaxon().pathMatcher(pathMatcher)
.parseJsonObject(StringReader(jsonString))
}
⚠️ 注意:onMatch
中的 value
只能是基础类型,不能是 JsonObject
或 JsonArray
。
7. Low-Level API
Low-Level API 允许你以 Map/List 的方式操作 JSON,不需要定义类。
✅ 示例 1:读取 JsonObject
@Test
fun givenJsonString_whenParser_thenGetJsonObject() {
val jsonString = StringBuilder("""
{
"name" : "HDD",
"capacityInGb" : 512,
"sizeInInch" : 2.5
}
""")
val parser = Parser.default()
val json = parser.parse(jsonString) as JsonObject
assertThat(json)
.hasSize(3)
.containsEntry("name", "HDD")
.containsEntry("capacityInGb", 512)
.containsEntry("sizeInInch", 2.5)
}
✅ 示例 2:读取 JsonArray
@Test
fun givenJsonStringArray_whenParser_thenGetJsonArray() {
val jsonString = StringBuilder("""
[
{ "name" : "SDD" },
{ "madeIn" : "Taiwan" },
{ "warrantyInYears" : 5 }
]""")
val parser = Parser.default()
val json = parser.parse(jsonString) as JsonArray<JsonObject>
assertSoftly({
softly ->
softly.assertThat(json).hasSize(3)
softly.assertThat(json[0]["name"]).isEqualTo("SDD")
softly.assertThat(json[1]["madeIn"]).isEqualTo("Taiwan")
softly.assertThat(json[2]["warrantyInYears"]).isEqualTo(5)
})
}
这种方式适合处理结构不固定或动态变化的 JSON 数据。
8. 总结
在本文中,我们介绍了 Klaxon 这个强大的 Kotlin JSON 处理库,涵盖了其四种主要 API:
- Object Binding:适合常规对象序列化
- Streaming:适合大文件流式处理
- JSON Path Query:适合按路径查询字段
- Low-Level:适合动态或结构不固定的 JSON 操作
你可以根据实际需求选择合适的 API 使用。
如需查看完整示例代码,请访问 GitHub。