Hir*_*iro 5 kotlin ktor kotlinx.serialization
我正在尝试制作一个简单的服务器,它提供 JSON 中的序列化列表。待序列化的List是官方博文多态序列化部分中的示例。
但是使用 ktor 的序列化功能,我得到以下异常。
21:53:25.536 [nioEventLoopGroup-4-1] ERROR ktor.application - Unhandled: GET - /
java.lang.IllegalStateException: Serializing collections of different element types is not yet supported. Selected serializers: [DirectMessage, BroadcastMessage]
at io.ktor.serialization.SerializerLookupKt.elementSerializer(SerializerLookup.kt:71)
Run Code Online (Sandbox Code Playgroud)
由于密封类是选择 Kotlin 的一个关键特性,我真的很想知道为什么不支持它。
ktor-serialization 不支持这一点有什么充分的理由吗?或者我应该发布一个问题以从SerializerLookup.kt中删除此检查?
我通过在 IntelliJ 中选择“新建项目”>“Kotlin”>“应用程序”来编写此代码。修改后的代码如下所示。
我的服务器.kt:
21:53:25.536 [nioEventLoopGroup-4-1] ERROR ktor.application - Unhandled: GET - /
java.lang.IllegalStateException: Serializing collections of different element types is not yet supported. Selected serializers: [DirectMessage, BroadcastMessage]
at io.ktor.serialization.SerializerLookupKt.elementSerializer(SerializerLookup.kt:71)
Run Code Online (Sandbox Code Playgroud)
我的 build.gradle.kts:
import io.ktor.application.*
import io.ktor.features.*
import io.ktor.response.*
import io.ktor.routing.*
import io.ktor.serialization.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import kotlinx.serialization.Serializable
@Serializable
sealed class Message {
abstract val content: String
}
@Serializable
data class BroadcastMessage(override val content: String) : Message()
@Serializable
data class DirectMessage(override val content: String, val recipient: String) : Message()
val data: List<Message> = listOf(
DirectMessage("Hey, Joe!", "Joe"),
BroadcastMessage("Hey, all!")
)
fun main() {
embeddedServer(Netty, port = 8080, host = "127.0.0.1") {
install(ContentNegotiation) {
json()
}
routing {
get("/") {
call.respond(data)
}
}
}.start(wait = true)
}
Run Code Online (Sandbox Code Playgroud)
正如 stacktrace 中所说this is not supported yet.,所以有一天它可能会到来。
但是,对于这种情况,仍然可以采取解决方法。该问题来自 Ktor,而不是 Kotlinx 序列化。因此,您可以将数据序列化为 JSON,然后将它们作为响应发送,如下所示:
fun Application.module(testing: Boolean = false) {
install(ContentNegotiation) { json() }
routing {
get("/") {
val data: List<Message> = listOf(
DirectMessage("Hey, Joe!", "Joe"),
BroadcastMessage("Hey, all!")
)
val string = Json.encodeToString(data)
call.respondText(string, contentType = ContentType.Application.Json)
}
}
}
@Serializable
sealed class Message {
abstract val content: String
}
@Serializable
data class BroadcastMessage(override val content: String) : Message()
@Serializable
data class DirectMessage(override val content: String, val recipient: String) : Message()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1890 次 |
| 最近记录: |