'Ktor Serializer for class 'Response' is not found
Plugin and dependeny:
id 'org.jetbrains.kotlin.plugin.serialization' version "$kotlin_version"
implementation "io.ktor:ktor-serialization:$ktor_version"
Application file:
fun main() {
embeddedServer(Netty, port = 8080, host = "0.0.0.0") {
install(ContentNegotiation) {
json()
}
userRouter()
}.start(wait = true)
}
UserRouter:
fun Application.userRouter() {
routing {
get("/users/{id}") {
val id = call.parameters["id"]?.toInt() ?: -1
val user = User("Sam", "[email protected]", "abc123")
val response = if (id == 1) {
Response("hahaha", false)
} else {
Response(user, true) //< - here, use String type will work
}
call.respond(response)
}
}
}
User:
@Serializable
data class User(
val name: String,
val email: String,
val password: String
)
Response:
@Serializable
data class Response<T>(
val data: T,
val success: Boolean
)
Logs:
2021-12-02 18:04:34.214 [eventLoopGroupProxy-4-1] ERROR ktor.application - Unhandled: GET - /users/7
kotlinx.serialization.SerializationException: Serializer for class 'Response' is not found.
Mark the class as @Serializable or provide the serializer explicitly.
at kotlinx.serialization.internal.Platform_commonKt.serializerNotRegistered(Platform.common.kt:91)
at kotlinx.serialization.SerializersKt__SerializersKt.serializer(Serializers.kt:155)
Any help would be appreciated.
Solution 1:[1]
The problem is that type for the response variable is Response<out Any> (the lowest common denominator between String and User types is Any) and the serialization framework cannot serialize the Any type.
Solution 2:[2]
That's werid, the following works, but to me they are just the same:
get("/users/{id}") {
val id = call.parameters["id"]?.toInt() ?: -1
val user = User("Sam", "[email protected]", "abc123")
/* val response = if (id == 1) { //<- determine response here won't work, why?
Response("hahaha", false)
} else {
Response(user, true)
}
call.respond(response)*/
if (id == 1) {
call.respond(Response("hahaha", false))
} else {
call.respond(Response(user, true))
}
}
Solution 3:[3]
You should give a type to a generic when you set a nullable generic to null, otherwise, the plugin doesn't know how to serialize it. for eg.
//define
@Serializable
data class Response<T>(
val data: T?,
val success: Boolean
)
///usage:
val response = Response<String>(null, false)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Aleksei Tirman |
| Solution 2 | Sam Chen |
| Solution 3 | PaulNUK |
