Kotlin JSON库使用
本文针对 Kotlin 项目中常用的 JSON 库的一些 API 使用进行一个基本介绍
kotlinx.serialization
Kotlin Serialization (https://github.com/Kotlin/kotlinx.serialization) 是 Kotlin 自带的处理序列化与反序列化的库,目前支持的格式有如下几种:
- JSON:kotlinx-serialization-json
- Protocol Buffers:kotlinx-serialization-protobuf
- CBOR:kotlinx-serialization-cbor
- Properties:kotlinx-serialization-properties
- HOCON:kotlinx-serialization-hocon (only on JVM)
详细使用文档:https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/serialization-guide.md
项目搭建
坐标引入参考:https://github.com/Kotlin/kotlinx.serialization,我这里使用Maven搭建项目,需要添加下面的maven配置:
<properties>
<kotlin.version>2.2.0</kotlin.version>
<serialization.version>1.9.0</serialization.version>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-serialization-json -->
<dependency>
<groupId>org.jetbrains.kotlinx</groupId>
<artifactId>kotlinx-serialization-json</artifactId>
<version>${serialization.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
<configuration>
<compilerPlugins>
<plugin>kotlinx-serialization</plugin>
</compilerPlugins>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-serialization</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
对象与JSON互转
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
@Serializable
class Project(val name: String, val language: String)
fun main() {
// 对象转JSON
val data = Project("kotlinx.serialization", "Kotlin")
// JSON转对象
val string = Json.encodeToString(data)
println(string) // {"name":"kotlinx.serialization","language":"Kotlin"}
val obj = Json.decodeFromString<Project>(string)
println(obj) // Project(name=kotlinx.serialization, language=Kotlin)
}
遍历JSON树结构
import kotlinx.serialization.json.*
fun main() {
// 1. 定义 JSON 字符串(实际开发中可来自网络/文件)
val jsonStr = """
{
"name": "Kotlin Serialization",
"version": 1.6,
"isStable": true,
"features": ["树形解析", "数据类序列化", "多格式支持"],
"config": {"enableCache": true, "timeout": 3000},
"emptyField": null
}
""".trimIndent()
// 2. 解析为 JSON 树根节点(JsonElement)
val jsonRoot: JsonElement = Json.parseToJsonElement(jsonStr)
// 3. 强制转换为 JsonObject(因为根节点是对象,需确保类型匹配,否则抛异常)
val jsonObject = jsonRoot.jsonObject // 安全转换:不会抛异常,返回 nullable
// 或强制转换(风险高,类型不匹配时抛 ClassCastException):
// val jsonObject = jsonRoot as JsonObject
println("解析后的 JSON 对象:$jsonObject")
}
JSON转Map
参考这个SO:https://stackoverflow.com/questions/44870961/how-to-map-a-json-string-to-kotlin-map
无需任何第三方库:
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.jsonObject
val input = """{
"_id" : { "some_id" : "593440eb7fa580d99d1abe85"} ,
"name" : "Firstname Secondname" ,
"reg_number" : "ATC/DCM/1016/230" ,
"oral" : 11 ,
"oral_percent" : 73 ,
"cat_1" : 57 ,
"cat_2" : 60 ,
"cat_average" : 59 ,
"assignment" : 90
}"""
val json = Json.parseToJsonElement(input)
val map = json.jsonObject.toMap()
Gson
使用时需引入 gson 的依赖:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.13.1</version>
</dependency>
Gson 是针对 java 对象的序列化框架。基于 Kotlin 对象使用 Gson 框架,会失去 Kotlin 的一些重要特性,比如:
- 非空类型安全。比如 Kotlin 类的属性定义为非空类型时,仍然可以将一个 null 赋值给它创建一个对象。跟预期不符
import com.google.gson.Gson
// 数据类:name 是非空字段(无 ?)
data class User(val name: String, val age: Int)
fun main() {
// JSON 中缺失 name 字段(仅含 age) 反序列化:非空字段 name 缺失 → 崩溃
val user = Gson().fromJson("""{"age": 25}""", User::class.java)
println(user.name) // null
}
解决该问题的方式就是给 name 加个?
- 参数默认值没有效果。Kotlin 属性可以赋予默认值。但是当使用 Gson 时,将会失去效果。
import com.google.gson.Gson
// 数据类:name 是非空字段(无 ?)
data class User(val name: String = "zs", val age: Int)
fun main() {
// JSON 中缺失 name 字段(仅含 age) 反序列化:非空字段 name 缺失 → 崩溃
val user = Gson().fromJson("""{"age": 25}""", User::class.java)
println(user.name) // null
}
这种情况下 gson 在找 User 的无参构造时没有找到,最终通过UnsafeAllocator.create()直接创建对象,不会走构造函数,给的默认值自然就不生效了
解决这个问题的方式是:给每个属性都赋一个初始值,这样就会生成一个无参的构造函数了,也就不会出现这种问题了
data class User(val name: String = "zs", val age: Int = 0)
即使已经给 data class 所有属性默认值了,但是当 json 中某个属性的值显式的为 null 时,null值还是会覆盖到原本的默认值,这就是问题所在:声明的时候不能为 null,写代码的时候也没异常提示,运行就会出现NPE。
Jackson
使用时需引入 jackson 的依赖:
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.16.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
<version>2.16.1</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.16.1</version>
</dependency>
</dependencies>
在 Kotlin 中使用 Jackson(核心依赖 jackson-databind + Kotlin 专用模块 jackson-module-kotlin)是比 Gson 更 “原生适配 Kotlin” 的 JSON 处理方案 —— 它能更好地支持空安全、默认值、数据类等 Kotlin 特性
关键特性(Kotlin 友好)
(1)默认值自动生效(无需额外依赖)
Jackson 原生支持 Kotlin 数据类的默认值,JSON 字段缺失时自动填充默认值(无需像 Gson 那样依赖 kotlin-reflect):
// JSON 缺失 age 字段(默认值 0)
val json = """{"name": "王五"}"""
val user = objectMapper.readValue(json, User::class.java)
println(user.age) // 输出:0(默认值生效)
(2)空安全适配
- 可空字段(
String?)接收null或缺失字段时,不会崩溃,直接赋值null; - 非空字段(
String)若 JSON 传递null,会抛出明确异常(InvalidFormatException),而非静默破坏空安全(Gson 2.10+ 存在的问题)。
其他的使用方法就和 java 中的差不多了,主要针对 kotlin 中的使用做说明

浙公网安备 33010602011771号