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

Ktor Server在Postman中返回406错误的技术求助

Ktor后端用户注册接口406错误排查

我正在开发Android笔记应用的后端服务,测试/v1/users/register路由的POST请求时遇到问题:调用http://127.0.0.1:8080/v1/users/register接口,Postman返回406错误,数据库无新增数据(已通过Ktor创建数据表)。

相关代码与日志

路由代码

fun Route.userRoutes(db: repo, jwtService: JwtService, hashFunction: (String) -> String) {
    route("/v1/users") {
        post("/register") {
            try {
                val registerRequest = call.receive<RegisterRequest>()

                // Handle registration logic
                val user = User(registerRequest.email, hashFunction(registerRequest.password), registerRequest.name)
                db.addUser(user)
                call.respond(HttpStatusCode.OK, SimpleResponse(true, jwtService.generateToken(user)))

            } catch (e: Exception) {
                // Handle registration errors
                call.respond(HttpStatusCode.BadRequest, SimpleResponse(false, "Missing Some Fields or Registration Failed"))
            }
        }
    }
}

RegisterRequest类

data class RegisterRequest(
    val email: String,
    val name: String,
    val password: String
)

SimpleResponse类

package com.example.data.model

data class SimpleResponse(
    val success: Boolean,
    val message: String
)

控制台日志

2023-12-29 21:42:28.514 [eventLoopGroupProxy-4-1] TRACE io.ktor.server.routing.Routing - Trace for [v1, users, register]
/, segment:0 -> SUCCESS @ /
  /session, segment:0 -> FAILURE "Selector didn't match" @ /session
  /json, segment:0 -> FAILURE "Selector didn't match" @ /json
  /, segment:0 -> SUCCESS @ /
    /(method:GET), segment:0 -> FAILURE "Selector didn't match" @ /(method:GET)
  /v1, segment:1 -> SUCCESS @ /v1
    /v1/users, segment:2 -> SUCCESS @ /v1/users
      /v1/users/register, segment:3 -> SUCCESS @ /v1/users/register
        /v1/users/register/(method:POST), segment:3 -> SUCCESS @ /v1/users/register/(method:POST)
      /v1/users/login, segment:2 -> FAILURE "Selector didn't match" @ /v1/users/login
Matched routes:
  "" -> "v1" -> "users" -> "register" -> "(method:POST)"
Route resolve result:
  SUCCESS @ /v1/users/register/(method:POST)
2023-12-30 21:04:26.349 [eventLoopGroupProxy-4-1] TRACE i.k.server.engine.DefaultTransform - No Default Transformations found for class io.ktor.utils.io.ByteBufferChannel and expected type TypeInfo(type=class com.example.data.model.RegisterRequest, reifiedType=class com.example.data.model.RegisterRequest, kotlinType=com.example.data.model.RegisterRequest) for call /v1/users/register
2023-12-30 21:04:26.375 [eventLoopGroupProxy-4-1] TRACE i.k.s.p.c.ContentNegotiation - No suitable content converter found for request type class com.example.data.model.RegisterRequest
2023-12-30 21:04:26.384 [eventLoopGroupProxy-4-1] TRACE io.ktor.server.sessions.Sessions - Sending session data for /v1/users/register: MY_SESSION
2023-12-30 21:04:26.407 [eventLoopGroupProxy-4-1] TRACE i.k.s.p.c.ContentNegotiation - No suitable content converter found for response type class com.example.data.model.SimpleResponse and body SimpleResponse(success=false, message=Missing Some Fields)

Postman请求体

{
    "name": "john",
    "email": "abcd@gmail.com",
    "password": "pass"
}

序列化配置代码

fun Application.configureSerialization() {

    install(ContentNegotiation) {

            Json {
                prettyPrint = true
                isLenient = true
                encodeDefaults = false
            }

    }

    routing {
        get("/json/gson") {
            call.respond(mapOf("hello" to "world"))
        }
    }
}

已确认信息

  • Postman请求头包含Content-Type: application/json和Accept: */*
  • Gradle使用最新版本依赖

问题分析与解决方案

从日志里的No suitable content converter found for request type class com.example.data.model.RegisterRequest可以明确,问题出在Ktor的ContentNegotiation插件没有正确配置序列化转换器,导致无法将请求的JSON数据反序列化为RegisterRequest对象,也无法将SimpleResponse序列化为JSON响应。

具体修复步骤:

  1. 添加序列化依赖:
    如果使用Kotlinx Serialization,确保Gradle中添加以下依赖(替换$ktor_version为你使用的Ktor版本):

    implementation("io.ktor:ktor-serialization-kotlinx-json-jvm:$ktor_version")
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")
    
  2. 修正ContentNegotiation配置:
    明确指定使用Kotlinx Json转换器,修改configureSerialization函数:

    import io.ktor.serialization.kotlinx.json.*
    import kotlinx.serialization.json.Json
    
    fun Application.configureSerialization() {
        install(ContentNegotiation) {
            json(Json {
                prettyPrint = true
                isLenient = true
                encodeDefaults = false
                ignoreUnknownKeys = true // 可选,忽略请求中多余字段
            })
        }
    
        routing {
            get("/json/gson") {
                call.respond(mapOf("hello" to "world"))
            }
        }
    }
    
  3. 为数据类添加序列化注解:
    给RegisterRequest和SimpleResponse添加@Serializable注解,Kotlinx Serialization需要该注解生成序列化代码:

    import kotlinx.serialization.Serializable
    
    @Serializable
    data class RegisterRequest(
        val email: String,
        val name: String,
        val password: String
    )
    
    package com.example.data.model
    
    import kotlinx.serialization.Serializable
    
    @Serializable
    data class SimpleResponse(
        val success: Boolean,
        val message: String
    )
    
  4. 确认Application调用序列化配置:
    检查主Application类是否调用了configureSerialization(),示例:

    fun main(args: Array<String>): Unit = io.ktor.server.netty.EngineMain.main(args)
    
    fun Application.module() {
        configureSerialization()
        // 其他配置:configureRouting、configureDatabase等
    }
    

完成以上步骤后重启服务,再次测试注册接口,即可正常完成JSON序列化/反序列化,406错误会消失,数据库也会新增用户数据。


内容的提问来源于stack exchange,提问作者Mr Sir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 02:54:51