You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Ktor与Exposed时遇ArrayList多态序列化注册错误求助

问题分析与解决方案

错误根源

你遇到的序列化错误,本质是直接返回了Exposed查询生成的ResultRow列表。ResultRow是Exposed内部的数据库结果容器,并非为序列化设计,Kotlinx Serialization无法自动处理这类未标记@Serializable的复杂类型,进而触发了列表序列化的异常。

修复步骤

1. 创建可序列化的DTO类

定义一个独立的数据传输对象(DTO),用来映射数据库字段并支持序列化:

package routes

import kotlinx.serialization.Serializable
import java.time.LocalDateTime

@Serializable
data class FilmDTO(
    val id: Int,
    val name: String,
    val director: String,
    val createTime: LocalDateTime,
    val updateTime: LocalDateTime
)

2. 修改查询逻辑,转换结果为DTO列表

将ResultRow手动映射为FilmDTO实例,避免直接返回Exposed内部对象:

fun Route.listOrdersRoute() {
    get("/films") {
        try {
            val films = transaction {
                addLogger(StdOutSqlLogger)
                Films.selectAll().map { row ->
                    FilmDTO(
                        id = row[Films.id].value,
                        name = row[Films.name],
                        director = row[Films.director],
                        createTime = row[Films.createTime],
                        updateTime = row[Films.updateTime]
                    )
                }
            }
            call.respond(films)
        } catch (ex: Exception) {
            call.respond(HttpStatusCode.InternalServerError, ex.localizedMessage)
        }
    }
}

3. 确保ContentNegotiation插件正确配置

在项目的主入口(如Main.kt)中,确认已安装并配置JSON序列化插件:

import io.ktor.serialization.kotlinx.json.*
import io.ktor.server.application.*
import io.ktor.server.plugins.contentnegotiation.*
import routes.listOrdersRoute

fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args)

fun Application.module() {
    install(ContentNegotiation) {
        json()
    }
    routing {
        listOrdersRoute()
    }
}

4. 统一Exposed依赖版本

你当前依赖中Exposed组件版本不一致(exposed-java-time为0.41.1,其余为0.40.1),统一版本可避免兼容性问题:
修改build.gradle.kts中的Exposed依赖:

implementation("org.jetbrains.exposed:exposed-core:0.41.1")
implementation("org.jetbrains.exposed:exposed-dao:0.41.1")
implementation("org.jetbrains.exposed:exposed-java-time:0.41.1")
implementation("org.jetbrains.exposed:exposed-jdbc:0.41.1")
runtimeOnly("org.jetbrains.exposed:exposed-jdbc:0.41.1")

为什么之前的尝试无效

你可能给Exposed的Film实体类加了@Serializable,但Entity类本身包含数据库连接状态等不可序列化的内部逻辑,并非适合作为接口返回的传输对象。必须使用独立的DTO类来剥离数据库层细节,实现安全序列化。

内容的提问来源于stack exchange,提问作者Adrian Aranda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 05:59:59