While Kotlin Serialization can be used for controllers, it doesn't work to serialize DTOs returned from Actuator @Endpoint
s.
When setting spring.http.converters.preferred-json-mapper=gson
(or jsonb), Gson is used for controllers and actuator endpoints.
When setting spring.http.converters.preferred-json-mapper=kotlin-serialization
, Kotlin Serialization is used for controllers, but Jackson is used for actuator endpoints.
This demo project (sorry that it's in Kotlin, but Kotlin Serialization only works with Kotlin types) demonstrates the issue.
I did a bit of debugging: A breakpoint in org.springframework.http.converter.AbstractKotlinSerializationHttpMessageConverter#canWrite
reveals:
In the WebMVC case:
- type
is com.example.kotlin_serialization.MyDto
- clazz
is class com.example.kotlin_serialization.MyDto
In the actuator case:
- type
is java.lang.Object
- clazz
is class com.example.kotlin_serialization.MyDto
And Spring Framework uses type
to see if there's a generated serializer for the type (the serializers are generated by a compiler plugin, see build.gradle
).
Comment From: wilkinsona
Generally speaking, when producing JSON, endpoints should return types that implement OperationResponseBody
. Doing so should ensure that they're serialised using Jackson irrespective of the application's preferred JSON mapper. We want that to be the case with any alternative mapper (GSON, JSON-B, Kotlin Serialisation, etc) on the classpath.
Comment From: mhalbritter
Ah, thanks for the hint, i'll try that.
Nevertheless, I think there's a bug somewhere, because it behaves differently with gson and jsonb than with Kotlin Serialization.