如何解决Kotlin序列化中LocalDate类型找不到序列化器的问题?
解决Kotlin Serialization中LocalDate/Date的序列化问题
针对LocalDate的解决方案
步骤1:引入Java 8序列化扩展库
先确保项目中添加kotlinx-serialization-java8依赖,它提供了Java 8日期时间类型(含LocalDate)的序列化器支持。
若使用Gradle Kotlin DSL,添加以下依赖:
implementation("org.jetbrains.kotlinx:kotlinx-serialization-java8:1.6.0")
注:版本号需与你使用的kotlinx-serialization-core版本保持一致
步骤2:配置序列化上下文
进行序列化/反序列化操作时,需使用包含Java 8序列化模块的Json实例:
import kotlinx.serialization.json.Json import kotlinx.serialization.modules.java8SerializersModule val json = Json { serializersModule = java8SerializersModule } // 序列化示例 val data = ProviderData("test", LocalDate.now(), LocalDate.now()) val jsonString = json.encodeToString(ProviderData.serializer(), data) // 反序列化示例 val parsedData = json.decodeFromString(ProviderData.serializer(), jsonString)
可选:替代@Contextual的方式
如果不想使用@Contextual注解,可直接为LocalDate字段指定序列化器:
import kotlinx.serialization.Serializable import kotlinx.serialization.java8.LocalDateSerializer import java.time.LocalDate @Serializable data class ProviderData( val provider: String, @Serializable(with = LocalDateSerializer::class) val serviceStartDate: LocalDate, @Serializable(with = LocalDateSerializer::class) val serviceEndDate: LocalDate )
这种方式无需额外配置Json实例的serializersModule,直接使用默认Json即可。
针对java.util.Date的解决方案
方式1:使用@Contextual+上下文配置
和LocalDate逻辑一致,添加依赖后,在Json配置中加入java8SerializersModule,然后给Date字段加上@Contextual注解:
import kotlinx.serialization.Serializable import kotlinx.serialization.Contextual import java.util.Date @Serializable data class ProviderData( val provider: String, @Contextual val serviceStartDate: Date, @Contextual val serviceEndDate: Date )
随后使用带java8SerializersModule的Json实例进行序列化/反序列化。
方式2:自定义序列化器
若不想引入扩展库,可自行编写Date的序列化器:
import kotlinx.serialization.KSerializer import kotlinx.serialization.Serializable import kotlinx.serialization.descriptors.PrimitiveKind import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder import java.util.Date object DateSerializer : KSerializer<Date> { override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Date", PrimitiveKind.LONG) override fun serialize(encoder: Encoder, value: Date) { encoder.encodeLong(value.time) } override fun deserialize(decoder: Decoder): Date { return Date(decoder.decodeLong()) } } // 使用示例 @Serializable data class ProviderData( val provider: String, @Serializable(with = DateSerializer::class) val serviceStartDate: Date, @Serializable(with = DateSerializer::class) val serviceEndDate: Date )
该方式会将Date序列化为时间戳(Long类型),反序列化时再转换回Date对象。
关键注意点
- 你的代码中
Serializable注解缺少@符号,需改为@Serializable,否则类无法被标记为可序列化。 - 依赖版本必须匹配:
kotlinx-serialization-java8的版本要和kotlinx-serialization-core版本一致,避免兼容性问题。
内容的提问来源于stack exchange,提问作者AAA
相关产品推荐
相关产品推荐

