当前位置: 首页 > news >正文

Kotlinx.serialization 项目集成

Gradle 安装

Android / JVM(Kotlin DSL)

// app/build.gradle.kts
plugins {id("org.jetbrains.kotlin.android")id("org.jetbrains.kotlin.plugin.serialization") // ← 必须
}dependencies {implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3") // 版本示例
}

Kotlin Multiplatform

// build.gradle.kts (KMP 根 module)
plugins {kotlin("multiplatform")id("org.jetbrains.kotlin.plugin.serialization")
}kotlin {androidTarget()jvm()ios()sourceSets {val commonMain by getting {dependencies {implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3")}}}
}

基础用法(最常用 3 行)

import kotlinx.serialization.*
import kotlinx.serialization.json.*@Serializable
data class User(val id: Long,val name: String,val email: String? = null,  // 可空 & 有默认值
)val json = Json { ignoreUnknownKeys = true } // 忽略后端多给的字段val u = User(1, "Alice")
val s: String = json.encodeToString(u)                // 对象 → JSON 字符串
val u2: User = json.decodeFromString<User>(s)         // JSON 字符串 → 对象

集合、嵌套、枚举

@Serializable
enum class Role { ADMIN, USER, GUEST }@Serializable
data class Team(val name: String,val members: List<User>,val tags: Set<String> = emptySet(),val roles: Map<Long, Role> = emptyMap()
)

Json 配置常用选项

val json = Json {ignoreUnknownKeys = true      // 后端多给字段也不报错encodeDefaults = true         // 输出默认值;关掉可减小体积prettyPrint = false           // 日常关;调试可开isLenient = true              // 宽松模式,允许非标准 JSONallowTrailingComma = trueexplicitNulls = false         // null 字段不主动输出// classDiscriminator = "type" // 多态时的类型标记字段名(见下)// namingStrategy = JsonNamingStrategy.SnakeCase // 字段命名转换(版本要求较新)
}

字段改名、别名、跳过

@Serializable
data class Article(@SerialName("id") val articleId: String,      // 接口字段叫 id,本地想叫 articleId@SerialName("title") val title: String,@JsonNames("cover", "thumbnail") val image: String? = null, // 兼容多个可能的字段名@Transient val cacheOnly: Boolean = false // 仅本地使用,不参与序列化
)

多态 & sealed class(后端返回不同“类型”的统一字段)

推荐 sealed class(编译期可知子类):

@Serializable
sealed class Msg {abstract val id: String
}@Serializable
@SerialName("text")
data class TextMsg(override val id: String, val text: String): Msg()@Serializable
@SerialName("image")
data class ImageMsg(override val id: String, val url: String): Msg()

Json 配置 + 解码:

val json = Json {classDiscriminator = "type" // 后端会给 {"type":"text", ...}ignoreUnknownKeys = true
}val msg: Msg = json.decodeFromString("""{"type":"text","id":"1","text":"hi"}""")
when (msg) {is TextMsg -> println(msg.text)is ImageMsg -> println(msg.url)
}

如果是“开放层级”多态(不是 sealed,或子类在别处定义),需要注册:

val json = Json {ignoreUnknownKeys = trueclassDiscriminator = "type"serializersModule = SerializersModule {polymorphic(Msg::class) {subclass(TextMsg::class, TextMsg.serializer())subclass(ImageMsg::class, ImageMsg.serializer())}}
}

自定义类型 / 自定义序列化器

dependencies {implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.4.1")
}
@Serializable
data class Event(val id: String,val at: kotlinx.datetime.Instant // 直接用
)

完全自定义(例如 UUID 或特殊格式)

import kotlinx.serialization.*
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.*
import java.util.UUID@Serializer(forClass = UUID::class)
object UUIDAsString : KSerializer<UUID> {override val descriptor: SerialDescriptor =PrimitiveSerialDescriptor("UUIDAsString", PrimitiveKind.STRING)override fun serialize(encoder: Encoder, value: UUID) {encoder.encodeString(value.toString())}override fun deserialize(decoder: Decoder): UUID =UUID.fromString(decoder.decodeString())
}@Serializable
data class WithUuid(@Serializable(with = UUIDAsString::class)val id: UUID
)

错误处理(生产可用模板)

import kotlinx.serialization.SerializationException
import kotlinx.serialization.json.Jsoninline fun <reified T> safeDecode(jsonString: String,json: Json = Json { ignoreUnknownKeys = true },onError: (String) -> Unit = {}
): T? {return try {json.decodeFromString<T>(jsonString)} catch (e: SerializationException) {onError("解析失败: ${e.message}\n片段: ${jsonString.take(300)}")null}
}

和 Ktor / Retrofit 集成

Ktor Client

implementation("io.ktor:ktor-client-core:2.3.7")
implementation("io.ktor:ktor-client-android:2.3.7")
implementation("io.ktor:ktor-client-content-negotiation:2.3.7")
implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.7")
val client = HttpClient(Android) {install(ContentNegotiation) {json(Json { ignoreUnknownKeys = true })}
}
@Serializable data class Todo(val id: Int, val title: String)
val todo: Todo = client.get("https://example.com/todo/1").body()

Retrofit(用 Kotlinx 的 Converter)

implementation("com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0")
implementation("com.squareup.retrofit2:retrofit:2.11.0")
val json = Json { ignoreUnknownKeys = true }
val retrofit = Retrofit.Builder().baseUrl("https://api.example.com/").addConverterFactory(json.asConverterFactory("application/json".toMediaType())).build()

与 Gson 的关键差异(迁移要点)

  • 无反射:kotlinx 在编译期生成 $$serializer,启动更快、可裁剪。

  • 默认值处理encodeDefaults 决定是否输出默认值;Gson 默认不输出 transient 字段,kotlinx 用 @Transient

  • 字段名:用 @SerialName@JsonNames;或全局 namingStrategy

  • 多态更安全sealed + classDiscriminator 明确标记类型。

  • 忽略未知字段:记得开 ignoreUnknownKeys = true,避免线上因后端加新字段而崩。

混淆 / 体积

  • 一般不需要额外 keep(因编译期生成并显式引用)。

  • 如果你自定义了 KSerializer 或用了反射式工厂,才可能需要补充 keep。

  • 体积优化:关闭 prettyPrint,必要时 explicitNulls=false,并按需关闭 encodeDefaults

常见坑与排查

  1. 忘记加插件id("org.jetbrains.kotlin.plugin.serialization")

  2. 字段名对不上:用 @SerialName 或开 namingStrategy

  3. 接口偶发多字段ignoreUnknownKeys = true

  4. 后端大小写不一致JsonNamingStrategy.SnakeCase 或 @JsonNames(...) 做兼容。

  5. 多态无法解析:确认 classDiscriminator 字段名与后端一致;开放多态要注册 SerializersModule

  6. 时间类型:优先 kotlinx-datetime;或写自定义 KSerializer

http://www.dtcms.com/a/617940.html

相关文章:

  • 使用Rust构建一个完整的DeepSeekWeb聊天应用
  • Kotlinx.serialization 使用指南
  • 后端日志收集与分析
  • 视频网站 php源码潜江资讯网招聘
  • 成都建立网站网站一直百度上搜不到是怎么回事
  • 测试案例拆解:ab测试/可用性测试一步到位
  • 【Android】模板化解决复杂场景的滑动冲突问题
  • LeetCode 热题 100——子串——和为 K 的子数组
  • JVM内存结构深度解析:堆、栈、方法区、元空间、直接内存
  • H-RDT:基于人类操作增强的双臂机器人操作研究
  • hysAnalyser --- UDP实时流分析使用指南
  • 象棋棋理基础
  • 要怎么推广网站全国工程招标信息网
  • 做教育网站多少钱如何选择企业建站公司
  • 高斯db的客户端连接工具
  • 网站建设与维护成本网站负责人核验照
  • 软件架构师技术一览与具体工作思考
  • [Java 算法] 双指针 2
  • Python语言设计模式:外观模式详解
  • 企业网站seo推广设计网站公司 露 联湖南岚鸿
  • 外贸建设网站公司微能力者恶魔网站谁做的
  • Python软件设计模式解析与实战
  • 工业互联网:连接未来制造的数字大脑
  • 基于单片机的水泵效率温差法测量与报警系统设计
  • 推荐工程笔记:设计模式/java与性能优化
  • 【安全函数】C语言安全字符串函数详解:告别缓冲区溢出的噩梦
  • 免费收录软文网站网站制作公司在哪里找
  • 3.FPGA位宽
  • Linux操作系统基础命令基础
  • 永恒之蓝内网横向渗透:原理详解+telnet法渗透实践(CVE-2017-0144)