未找到“响应”类的 Ktor 序列化程序
Posted
技术标签:
【中文标题】未找到“响应”类的 Ktor 序列化程序【英文标题】:Ktor Serializer for class 'Response' is not found 【发布时间】:2022-01-09 10:19:21 【问题描述】:插件和依赖:
id 'org.jetbrains.kotlin.plugin.serialization' version "$kotlin_version"
implementation "io.ktor:ktor-serialization:$ktor_version"
Application
文件:
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", "sam@gmail.com", "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
)
日志:
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)
任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:问题是response
变量的类型是Response<out Any>
(String
和User
类型之间的最小公分母是Any
)并且序列化框架无法序列化Any
类型。
【讨论】:
奇怪的是,它在本教程中有效:youtu.be/uhNF4wK4hWU。 @SamChen,教程不同,它使用两个单独的响应调用(具有不同的参数类型)。此处的响应被具体化,因此它实际上捕获了静态类型,在问题案例中,静态类型是两个响应之间的共同点。在没有鉴别器的情况下返回变量类型存在不同的问题,但这是一个不同的讨论。【参考方案2】:这很奇怪,以下工作,但对我来说它们是一样的:
get("/users/id")
val id = call.parameters["id"]?.toInt() ?: -1
val user = User("Sam", "sam@gmail.com", "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))
【讨论】:
他们不一样。在这种情况下,第一个respond
接收Response<String>
类型的值,第二个响应接收Response<User>
类型的值。原始案例使用单个变量来保存两者,因此类型为Response<Any>
。请注意,kotlinx.serialization 是一个静态框架,使用静态类型,而不是运行时类型。
@Paul de Vrieze 有帮助,谢谢。【参考方案3】:
当你将一个可以为空的泛型设置为空时,你应该给一个泛型一个类型,否则,插件不知道如何序列化它。 例如。
//define
@Serializable
data class Response<T>(
val data: T?,
val success: Boolean
)
///usage:
val response = Response<String>(null, false)
【讨论】:
以上是关于未找到“响应”类的 Ktor 序列化程序的主要内容,如果未能解决你的问题,请参考以下文章
“未找到转换:类 io.ktor.utils.io.ByteChannelNative”错误使用 Ktor
数据类中的默认参数未使用 ktor 序列化程序转换为 json
Ktor:如何序列化/反序列化 JSON-API (vnd.api+json)
Ktor WebSockets:kotlinx.serialization.SerializationException:找不到类“DefaultClientWebSocketSession”的序列化