I am using Gson to parse JSON. What surprised me is that if I have a field of type String
in my POJO class and I have a number
in JSON it's parsed correctly without throwing an exception. Similarly the other way - I wrote this test to illustrate:
data class Parsed(
val testString: String,
val testNumber: Int,
)
@Test
fun `test gson type parsing`() {
val gson = Gson()
val json = "{ \"testString\" : 1, \"testNumber\" : \"1\"}"
val parsed = gson.fromJson(json, Parsed::class.java)
assertThat(parsed.testString).isEqualTo("1") // passes
assertThat(parsed.testNumber).isEqualTo(1) // passes
// expected an exception because number is parsed into a string field and string is parsed into number
}
Is there any way to change this behavior? (Only found setLenient()
on GsonBuilder
but it's not related to this)
I don't think you can turn of type coercion in gson. Your best bet would probably be to write a custom deserializer that prevents this.
That being said, contemplate not using gson in kotlin code as it completely circumvents the null safety of the language. You are better of using a serialization framework that is kotlin aware, such as jackson (with kotlin plugin) or kotlinx-serialization.
Aditionally it seems like jackson allows to turn this specific type coercion off, using this flag: https://fasterxml.github.io/jackson-databind/javadoc/2.9/com/fasterxml/jackson/databind/MapperFeature.html#ALLOW_COERCION_OF_SCALARS
Kotlinx-serialization seems to not have such an option: https://github.com/Kotlin/kotlinx.serialization/issues/1042