-
Notifications
You must be signed in to change notification settings - Fork 38.9k
Description
This is possibly an issue with Spring Boot and not the framework, so let me know if I should move the issue there.
Project setup
In a Spring Boot 4.0 project (haven't tested older versions) add the kotlinx.serialization plugin and json library. Add a type that is marked as @Serializable by the kotlinx.serialization library. Implement an endpoint that returns one of the types described in the next section.
@Serializable
data class DemoEntity(
val id: Int = -1,
@SerialName("sval_kotlinx")
@JsonProperty("sval_jackson")
val sval: String,
) {
val customSval: String
get() = "CUSTOM!$sval"
}What happens
Depending on what type is returned, a different serialization library is used, even though kotlinx.serialization supports the serialization of all the types and could be used for all.
| Type | Serializer used | Demo Endpoint |
|---|---|---|
DemoEntity |
kotlinx.serialization ✔️ |
/demo1 |
Map<Int, DemoEntity> |
kotlinx.serialization ✔️ |
/demo2 |
List<DemoEntity> |
kotlinx.serialization ✔️ |
/demo3 |
Map<Int, List<DemoEntity>> |
Jackson 🚫 | /demo4 |
This is an issue, since kotlinx.serialization ignores properties without a backing field (the customSval in the example) during serialization. Objects serialized by kotlinx.serialization don't include the customSval field (what I want), but when Spring falls back to Jackson, it is included (and later fails deserialization with kotlinx.serialization in a client).
In this case, this could be easily solved by adding @JsonIgnore to the field, so Jackson also ignores it, or using Json { ignoreUnknownKeys = true } as the deserializer in the client. However, this could cause issues in more complex examples and also requires the developer to maintain two libraries and have double annotations (one for each library) whenever something non-standard is used.
Minimal example
Removing the jackson-module-kotlin dependency from build.gradle doesn't change the results of the experiment. Field name annotations are only used to further demonstrate the issues.
https://github.com/Kwasow/spring-boot-issue-kotlinx-serialization