I'm using GSON to serialize some platform data. When I use @SerialName
to capture platform data with a different naming convention in my app, it works for other types, but not Boolean
types. As a simple example, if I have a class like...
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class Person (
@SerialName("first_name") val firstName: String? = null,
@SerialName("last_name") val lastName: String? = null,
val age: Int? = null
)
... everything works fine. The serializer finds first_name
, last_name
and age
in the data and properly set the properties for the Person
.
However, when I try to add a Boolean
...
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class Person (
@SerialName("first_name") val firstName: String? = null,
@SerialName("last_name") val lastName: String? = null,
val age: Int? = null,
@SerialName("can_sing") val canSing: Boolean? = null
)
... the serializer does not catch and assign can_sing
. It is strange that it works with a String
but not a Boolean
. Can any explain why I am seeing this behavior? I can work around this (for example, I can do val can_sing: Boolean? = null
and it works), but I'm just wonder why @SerialName
doesn't seem to work for a Boolean
, or if I'm just missing something obvious.
You are mixing the Gson and Kotlin annotation types - Gson uses @SerializedName
not @SerialName
. I am not sure how your string types even work in that case (maybe something in how you call Gson that isn't included in the question).
As an example, the first class here (Person
) can be serialized with the Kotlin serialization library, the second with Gson:
Kotlin annotations
@Serializable
data class Person (
@SerialName("first_name") val firstName: String? = null,
@SerialName("last_name") val lastName: String? = null,
val age: Int? = null,
@SerialName("can_sing") val canSing: Boolean? = null
)
Gson Annotations
data class PersonGson (
@SerializedName("first_name") val firstName: String? = null,
@SerializedName("last_name") val lastName: String? = null,
val age: Int? = null,
@SerializedName("can_sing") val canSing: Boolean? = null
)
Examples
Running this unit test with the Kotlin serialization library:
@Test
fun testJsonKotlin() {
val test = Person("hello", "world", 42, false)
val json = Json.encodeToString(test)
println(json)
val t2 = Json.decodeFromString<Person>(json)
println(t2)
}
produces the expected output:
{"first_name":"hello","last_name":"world","age":42,"can_sing":false}
Person(firstName=hello, lastName=world, age=42, canSing=false)
Doing that with Gson
@Test
fun testJsonGsonMixed() {
val testp = Person("hello", "world", 42, false)
val json = Gson().toJson(testp)
println(json)
val t2 = Gson().fromJson(json, Person::class.java)
println(t2)
}
technically works, but ignores the serialized name annotations (for all the cases, not just the boolean)
{"firstName":"hello","lastName":"world","age":42,"canSing":false}
Person(firstName=hello, lastName=world, age=42, canSing=false)
Using the Gson-annotated class with Gson
@Test
fun testJsonGson() {
val test = PersonGson("hello", "world", 42, false)
val json = Gson().toJson(test)
println(json)
val t2 = Gson().fromJson(json, PersonGson::class.java)
println(t2)
}
gives the correct response again
{"first_name":"hello","last_name":"world","age":42,"can_sing":false}
PersonGson(firstName=hello, lastName=world, age=42, canSing=false)