Kotlin序列化配置与JSON处理实践指南

Kotlin序列化配置与JSON处理实践指南

1. Kotlin Serialization 基础配置

1.1 依赖引入与插件配置

在Kotlin项目中使用Serialization需要先配置相关依赖。对于Gradle构建的项目,需要在项目级和模块级的build.gradle.kts文件中分别添加以下配置:

// 项目级build.gradle.kts plugins { kotlin("jvm") version "1.9.0" kotlin("plugin.serialization") version "1.9.0" // 关键插件 } // 模块级build.gradle.kts dependencies { implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0") }

这里有几个关键点需要注意:

  1. 插件版本必须与Kotlin编译器版本保持一致
  2. 序列化插件需要在所有使用它的模块中启用
  3. 对于Android项目,还需要确保启用了Kotlin的元编程支持

提示:如果遇到"Unresolved reference: serialization"错误,请检查是否在项目级build.gradle中正确应用了插件。

1.2 基础数据类定义

定义一个可序列化的数据类非常简单,只需要添加@Serializable注解:

import kotlinx.serialization.Serializable @Serializable data class User( val id: Int, val name: String, val email: String? = null, // 可空类型 @SerialName("created_at") val createTime: Long // 自定义JSON字段名 )

这个简单的数据类已经包含了几个重要特性:

  • 空安全处理(email字段)
  • 默认值(email默认为null)
  • 字段名映射(created_at映射到createTime)

2. JSON序列化核心操作

2.1 基本序列化与反序列化

使用Json对象进行基础转换操作:

import kotlinx.serialization.encodeToString import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json val json = Json { ignoreUnknownKeys = true // 重要配置:忽略未知字段 isLenient = true // 允许非严格JSON格式 } // 序列化 val user = User(1, "Alice", "alice@example.com", System.currentTimeMillis()) val jsonString = json.encodeToString(user) // 反序列化 val parsedUser = json.decodeFromString<User>(jsonString)

2.2 高级配置选项

Json构建器支持多种配置选项:

val customJson = Json { encodeDefaults = true // 序列化默认值 explicitNulls = false // 不序列化null值 coerceInputValues = true // 使用默认值处理缺失字段 allowStructuredMapKeys = true // 允许复杂类型作为Map键 prettyPrint = true // 美化输出 useArrayPolymorphism = true // 多态数组处理 }

这些配置项的组合可以满足绝大多数业务场景的需求。例如,在API开发中,通常会设置:

  • ignoreUnknownKeys = true(兼容API字段增减)
  • explicitNulls = false(减少传输数据量)
  • coerceInputValues = true(保证数据完整性)

3. 复杂场景处理

3.1 自定义序列化器

对于特殊类型(如Date),需要实现KSerializer接口:

import kotlinx.serialization.* import java.time.LocalDate import java.time.format.DateTimeFormatter object LocalDateSerializer : KSerializer<LocalDate> { private val formatter = DateTimeFormatter.ISO_LOCAL_DATE override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("LocalDate", PrimitiveKind.STRING) override fun serialize(encoder: Encoder, value: LocalDate) { encoder.encodeString(formatter.format(value)) } override fun deserialize(decoder: Decoder): LocalDate { return LocalDate.parse(decoder.decodeString(), formatter) } } @Serializable data class Event( val name: String, @Serializable(with = LocalDateSerializer::class) val date: LocalDate )

3.2 多态类型处理

处理继承体系时,需要使用@Polymorphic注解:

@Serializable abstract class Response @Serializable @SerialName("success") data class SuccessResponse(val data: String) : Response() @Serializable @SerialName("error") data class ErrorResponse(val code: Int, val message: String) : Response() val json = Json { classDiscriminator = "type" // 类型标识字段名 serializersModule = SerializersModule { polymorphic(Response::class) { subclass(SuccessResponse::class) subclass(ErrorResponse::class) } } }

4. 性能优化与生产实践

4.1 缓存序列化器实例

对于高性能场景,应该重用Json实例:

object JsonSerializer { val defaultJson = Json { ignoreUnknownKeys = true coerceInputValues = true } private val cachedSerializers = mutableMapOf<KClass<*>, KSerializer<*>>() fun <T : Any> getSerializer(kClass: KClass<T>): KSerializer<T> { return cachedSerializers.getOrPut(kClass) { kClass.serializer() } as KSerializer<T> } }

4.2 流式处理大JSON

对于大文件处理,可以使用Json.decodeFromStream:

fun parseLargeJsonFile(file: File): List<User> { return file.inputStream().use { stream -> Json.decodeFromStream<List<User>>(stream) } }

4.3 Android混淆配置

在proguard-rules.pro中添加:

-keep class kotlinx.serialization.** { *; } -keepclasseswithmembers class * { @kotlinx.serialization.Serializable <fields>; }

5. 常见问题排查

5.1 序列化失败场景

  1. 缺少@Serializable注解
  2. 尝试序列化非数据类
  3. 属性可见性不是public
  4. 使用了不支持的类型(如Java集合类)

5.2 性能问题诊断

  1. 避免频繁创建Json实例
  2. 对于复杂对象,考虑预编译序列化器
  3. 大文件使用流式处理
  4. 注意后端服务的JSON处理能力

5.3 与其他库的兼容性

  1. 与Retrofit配合使用时需要添加转换器:
implementation("com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:1.0.0")
  1. 与Spring Boot集成时需要配置HttpMessageConverter

在实际项目中,我通常会建立一个serialization模块,集中管理所有序列化相关配置,包括:

  • 自定义序列化器
  • 公共Json配置
  • 类型别名定义
  • 跨模块共享的数据模型

这种集中管理的方式可以确保整个项目使用一致的序列化策略,避免因配置不一致导致的问题。