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
相关产品推荐
相关产品推荐

