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!
Kotlin Serialization does not use reflection, so you cannot accidentally deserialize a class which was not supposed to be serializable. We fix it by adding the @Serializable annotation.
kotlinx. serialization provides sets of libraries for all supported platforms – JVM, JavaScript, Native – and for various serialization formats – JSON, CBOR, protocol buffers, and others. You can find the complete list of supported serialization formats below. All Kotlin serialization libraries belong to the org.
In Kotlin, data serialization tools are available in a separate component, kotlinx.serialization. It consists of two main parts: the Gradle plugin – org.jetbrains.kotlin.plugin.serialization and the runtime libraries.
(Kotlinx library is multiplatform library you can use it with Kotlin multiplatform in your JS, iOS, Android, Web project). If you use it in your Android project and you are using Retrofit, then there is a good news there is an official lib to use Kotlinx serialization with Retrofit (thanks for Jake Wharton !!!).
HashMap is a concrete class which implements serializable. You can use any concrete sub class of Map which implements serializable val filters: HashMap<String, Any?> = HashMap () filters.put ("a", 2)
Serialization is the process of converting data used by an application to a format that can be transferred over a network or stored in a database or a file. In turn, deserialization is the opposite process of reading data from an external source and converting it into a runtime object.
@file:UseSerializers(LocalDateSerializer::class)
put this in the file where your object is declared it should use LocalDateSerializer every time it sees Local Date
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With