Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ms-access/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 为什么ktor序列化中不支持序列化不同元素类型的集合?_Kotlin_Ktor_Kotlinx.serialization - Fatal编程技术网

Kotlin 为什么ktor序列化中不支持序列化不同元素类型的集合?

Kotlin 为什么ktor序列化中不支持序列化不同元素类型的集合?,kotlin,ktor,kotlinx.serialization,Kotlin,Ktor,Kotlinx.serialization,我试图制作一个简单的服务器,它以JSON格式提供序列化列表。要序列化的列表是的多态序列化部分中的示例 但是使用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

我试图制作一个简单的服务器,它以JSON格式提供序列化列表。要序列化的列表是的多态序列化部分中的示例

但是使用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)
既然sealed类是选择Kotlin的关键特性,我真想知道为什么不支持它

ktor序列化不支持这一点有什么好的理由吗?或者我应该发布一个问题来删除此支票吗


我在IntelliJ中选择New Project>Kotlin>Application编写了这段代码。修改后的代码如下所示

My server.kt:

导入io.ktor.application*
导入io.ktor.features*
导入io.ktor.response*
导入io.ktor.routing*
导入io.ktor.serialization*
导入io.ktor.server.engine*
导入io.ktor.server.netty*
导入kotlinx.serialization.Serializable
@可序列化
密封类消息{
内容摘要:字符串
}
@可序列化
数据类BroadcastMessage(覆盖val内容:字符串):Message()
@可序列化
数据类DirectMessage(覆盖val内容:字符串,val收件人:字符串):消息()
val数据:List=listOf(
DirectMessage(“嘿,乔!”,“乔”),
广播信息(“嗨,大家好!”)
)
主要内容(){
嵌入式服务器(Netty,端口=8080,主机=“127.0.0.1”){
安装(内容协商){
json()
}
路由{
获取(“/”){
呼叫.应答(数据)
}
}
}.start(等待=真)
}
我的build.gradle.kts:

import org.jetbrains.kotlin.gradle.tasks.kotlincomfile
插件{
kotlin(“jvm”)版本“1.4.10”
应用
kotlin(“plugin.serialization”)版本“1.4.10”
}
group=“com.example.ktor.serialization”
version=“1.0-SNAPSHOT”
存储库{
mavenCentral()
jcenter()
马文{
url=uri(“https://dl.bintray.com/kotlin/ktor")
}
马文{
url=uri(“https://dl.bintray.com/kotlin/kotlinx")
}
}
依赖关系{
测试实施(kotlin(“test-junit5”))
实现(“io.ktor:ktor服务器网络:1.4.1”)
实现(“io.ktor:ktor html生成器:1.4.1”)
实现(“io.ktor:ktor序列化:1.4.1”)
实现(“org.jetbrains.kotlinx:kotlinxhtmljvm:0.7.2”)
实现(“org.jetbrains.kotlinx:kotlinx序列化json:1.0.0”)
实现(“ch.qos.logback:logbackclassic:1.2.3”)
}
tasks.withType(){
kotlinOptions.jvmTarget=“11”
}
应用{
mainClassName=“ServerKt”
}

正如stacktrace
中所说,这还不受支持。
,因此它可能有一天会出现

但是,对于这种情况,仍然可以采取变通办法。 问题来自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()
fun Application.module(测试:Boolean=false){
安装(ContentNegotiation){json()}
路由{
获取(“/”){
val数据:List=listOf(
DirectMessage(“嘿,乔!”,“乔”),
广播信息(“嗨,大家好!”)
)
val string=Json.encodeToString(数据)
call.respondText(字符串,contentType=contentType.Application.Json)
}
}
}
@可序列化
密封类消息{
内容摘要:字符串
}
@可序列化
数据类BroadcastMessage(覆盖val内容:字符串):Message()
@可序列化
数据类DirectMessage(覆盖val内容:字符串,val收件人:字符串):消息()

原因是我们没有特定的类型信息,只能在运行时分析实例类。分析和运行时类型的交集不是一项容易的任务,而且肯定会非常低效,这在服务器端是不可接受的

使用
typeOf
可能会有所帮助,但我们尚未分析此类更改(包括分配配置文件)对性能的影响。另一个原因是我们不知道
typeOf
(它不存在)和
call.respond
是在没有它的情况下设计的,所以这个更改肯定是一个突破性的更改