Reputation: 101
I'm using Kotlin 1.3.10 (and bound to this version) and Kotlinx-Serialization 0.13 and I'm having trouble with serializing a map in Kotlinx-Serialization.
I have the following code:
@Serializer(forClass = LocalDate::class)
object LocalDateSerializer : KSerializer<LocalDate> {
private val formatter: DateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd")
override val descriptor: SerialDescriptor
get() = StringDescriptor.withName("LocalDate")
override fun serialize(encoder: Encoder, obj: LocalDate) {
encoder.encodeString(obj.format(formatter))
}
override fun deserialize(decoder: Decoder): LocalDate {
return LocalDate.parse(decoder.decodeString(), formatter)
}
}
@Serializable
data class MyClass (
val students: Map<String,LocalDate>
)
@UnstableDefault
@Test
fun decodeEncodeSerialization() {
val jsonParser = Json(
JsonConfiguration(
allowStructuredMapKeys = true
)
)
val mc = MyClass(
mapOf("Alex" to LocalDate.of(1997,2,23))
)
val mcJson = jsonParser.stringify(MyClass.serializer(), mc)
val mcObject = jsonParser.parse(MyClass.serializer(), mcJson)
assert(true)
}
There is a red line when inspecting the code which says "Serializer has not been found for 'LocalDate'. To use context serializer as fallback, explicitly annotate type or property with @ContextualSerialization."
With other types of fields, it would have been enough to add @Serialization to it.
@Serializable
data class Student (
val name: String,
@Serializable(with = LocalDateSerializer::class)
val dob: LocalDate
)
But with a map I can't seem to figure out how. I put it above, or beside the object...
@Serializable
data class MyClass (
val students: Map<String,@Serializable(with = LocalDateSerializer::class) LocalDate> //here
//or
//@Serializable(with = LocalDateSerializer::class)
//val students2: Map<String, LocalDate> //here
)
...but tests still fail with
kotlinx.serialization.SerializationException: Can't locate argument-less serializer for class java.time.LocalDate (Kotlin reflection is not available). For generic classes, such as lists, please provide serializer explicitly.
And the workaround I have for it is
@Serializable
data class MyClass (
val students: List<Student>
)
@Serializable
data class Student (
val name: String,
@Serializable(with = LocalDateSerializer::class)
val dob: LocalDate
)
Is there a way I would not resort to the workaround? Thank you!
Upvotes: 9
Views: 6268
Reputation: 13937
@file:UseSerializers(LocalDateSerializer::class)
put this in the file where your object is declared it should use LocalDateSerializer every time it sees Local Date
Upvotes: 1