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

Ktor中StatusPages模块序列化失效问题求助

问题解决:Ktor StatusPages返回序列化对象时出现406 Not Acceptable

问题原因

你的ErrResponseBody是定义在mainModule函数内部的局部数据类,kotlinx.serialization编译器插件无法为局部类生成正确的序列化器,导致ContentNegotiation模块找不到对应的内容转换器,最终返回406错误。而返回字符串不需要序列化器处理,因此可以正常响应。

解决方案

方案1:将ErrResponseBody改为顶层类

把ErrResponseBody从mainModule内部移到文件顶层(或单独的DTO文件中),确保kotlinx.serialization能正确生成并识别序列化器:

// 移到文件顶层,脱离任何函数内部
@Serializable
data class ErrResponseBody(val errorType: String, val errorDetail: String)

fun Application.mainModule() {
    install(ContentNegotiation) { json() }
    
    install(StatusPages) {
        exception<Throwable> { call, cause ->
            when(cause) {
                is HttpException -> {
                    val responseBody = ErrResponseBody(cause.errorType, cause.errorDetail)
                    call.respond(cause.statusCode, responseBody)
                }
                else -> {
                    val responseBody = ErrResponseBody("Internal server error", "")
                    call.respond(HttpStatusCode.InternalServerError, responseBody)
                }
            }
        }
    }
}

方案2:手动指定序列化器(适合保留局部类场景)

如果必须将ErrResponseBody保留为局部类,在调用respond时手动传入生成的序列化器:

install(StatusPages) {
    exception<Throwable> { call, cause ->
        when(cause) {
            is HttpException -> {
                val responseBody = ErrResponseBody(cause.errorType, cause.errorDetail)
                // 手动指定序列化器
                call.respond(
                    cause.statusCode,
                    responseBody,
                    serializer = ErrResponseBody.serializer()
                )
            }
            else -> {
                val responseBody = ErrResponseBody("Internal server error", "")
                call.respond(
                    HttpStatusCode.InternalServerError,
                    responseBody,
                    serializer = ErrResponseBody.serializer()
                )
            }
        }
    }
}

方案3:检查ContentNegotiation的Json配置

如果有特殊序列化需求,确保自定义的Json配置正确传入ContentNegotiation:

install(ContentNegotiation) {
    json(Json {
        ignoreUnknownKeys = true
        prettyPrint = true
        // 根据需要添加其他序列化配置
    })
}

验证

修改后重启服务,触发AuthGuard抛出异常,此时应能正常返回序列化后的JSON响应,不再出现406错误。

内容的提问来源于stack exchange,提问作者Kristiano Odadu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 17:53:12