Ktor 与 Kmongo 和 kotlinx.serialization
Ktor with Kmongo and kotlinx.serialization
我有一个设置,我将 KTor 与 KMongo 和 Kotlinx.Serialization 一起使用。
Kmongo 部分有效,我可以获取并放入我的 Class
@Serializable
data class Task(@ContextualSerialization @SerialName("_id") val _id : Id<Task> = newId(),
val title : String = "",
val description : String = ""
)
进入数据库并检索。一切都完美无缺。
但是当我尝试通过 rest 调用将该对象发送到前端时,再次使用 Kotlinx.Serialization。
get<Tasks>{ task ->
val dao by di().instance<Dao>();
val task = Task( title = "task1", description = "task1description");
val foundTask = dao.read(task);
if(foundTask != null){
call.respond(foundTask)
} else {
call.respond("didn't find anything")
}
}
它抛出了这个期望:
kotlinx.serialization.SerializationException: Can't locate argument-less serializer for class WrappedObjectId. For generic classes, such as lists, please provide serializer explicitly.
at kotlinx.serialization.PlatformUtilsKt.serializer(PlatformUtils.kt:21)
at kotlinx.serialization.modules.SerialModuleExtensionsKt.getContextualOrDefault(SerialModuleExtensions.kt:29)
at kotlinx.serialization.ContextSerializer.serialize(ContextSerializer.kt:29)
at kotlinx.serialization.json.internal.StreamingJsonOutput.encodeSerializableValue(StreamingJsonOutput.kt:227)
at kotlinx.serialization.builtins.AbstractEncoder.encodeSerializableElement(AbstractEncoder.kt:72)
现在我发现这是因为 kotlin.serialization json 有 2 个实例。并且 KMongo 上的一个不与另一个共享它的序列化器。
所以我将 KMongo 的序列化程序添加到 Ktor 的另一个实例
install(ContentNegotiation) {
json(
json = Json(DefaultJsonConfiguration.copy(prettyPrint = true), context = kmongoSerializationModule),
contentType = ContentType.Application.Json
)
}
现在我得到了
java.lang.ClassCastException: class kotlinx.serialization.json.internal.StreamingJsonOutput cannot be cast to class com.github.jershell.kbson.BsonEncoder (kotlinx.serialization.json.internal.StreamingJsonOutput and com.github.jershell.kbson.BsonEncoder are in unnamed module of loader 'app')
所以我的问题是为什么会发生这种情况以及如何解决它?
编辑:此问题已修复。
我还在 KMongo github 上发布了这个问题,基本上得到了即时回复,这是针对 Jackson 的修复,但尚未针对 Kotlinx.serialization。
有人会解决这个问题。
编辑:已修复
我有一个设置,我将 KTor 与 KMongo 和 Kotlinx.Serialization 一起使用。
Kmongo 部分有效,我可以获取并放入我的 Class
@Serializable
data class Task(@ContextualSerialization @SerialName("_id") val _id : Id<Task> = newId(),
val title : String = "",
val description : String = ""
)
进入数据库并检索。一切都完美无缺。
但是当我尝试通过 rest 调用将该对象发送到前端时,再次使用 Kotlinx.Serialization。
get<Tasks>{ task ->
val dao by di().instance<Dao>();
val task = Task( title = "task1", description = "task1description");
val foundTask = dao.read(task);
if(foundTask != null){
call.respond(foundTask)
} else {
call.respond("didn't find anything")
}
}
它抛出了这个期望:
kotlinx.serialization.SerializationException: Can't locate argument-less serializer for class WrappedObjectId. For generic classes, such as lists, please provide serializer explicitly.
at kotlinx.serialization.PlatformUtilsKt.serializer(PlatformUtils.kt:21)
at kotlinx.serialization.modules.SerialModuleExtensionsKt.getContextualOrDefault(SerialModuleExtensions.kt:29)
at kotlinx.serialization.ContextSerializer.serialize(ContextSerializer.kt:29)
at kotlinx.serialization.json.internal.StreamingJsonOutput.encodeSerializableValue(StreamingJsonOutput.kt:227)
at kotlinx.serialization.builtins.AbstractEncoder.encodeSerializableElement(AbstractEncoder.kt:72)
现在我发现这是因为 kotlin.serialization json 有 2 个实例。并且 KMongo 上的一个不与另一个共享它的序列化器。
所以我将 KMongo 的序列化程序添加到 Ktor 的另一个实例
install(ContentNegotiation) {
json(
json = Json(DefaultJsonConfiguration.copy(prettyPrint = true), context = kmongoSerializationModule),
contentType = ContentType.Application.Json
)
}
现在我得到了
java.lang.ClassCastException: class kotlinx.serialization.json.internal.StreamingJsonOutput cannot be cast to class com.github.jershell.kbson.BsonEncoder (kotlinx.serialization.json.internal.StreamingJsonOutput and com.github.jershell.kbson.BsonEncoder are in unnamed module of loader 'app')
所以我的问题是为什么会发生这种情况以及如何解决它?
编辑:此问题已修复。
我还在 KMongo github 上发布了这个问题,基本上得到了即时回复,这是针对 Jackson 的修复,但尚未针对 Kotlinx.serialization。
有人会解决这个问题。
编辑:已修复