0Pricing
Kotlin Academy · 课时

路由与类型化参数

使用路径参数和查询参数定义路由,并通过 route 代码块将它们分组。

路由与类型化参数 是 CoddyKit 上的免费 Kotlin Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Kotlin Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Kotlin Academy 课程共包含 4 节课。

Ktor 路由基础

Ktor 中的路由是通过 install(Routing) { ... } 安装的插件,也可以使用简写形式 routing { ... }。路由使用 HTTP 方法函数定义:get、post、put、delete、patch。

routing {
    get("/hello") { call.respondText("Hello!") }
    post("/items") { /* handle POST */ }
}

路径参数

使用 {name} 定义路径参数。通过 call.parameters["name"] 访问它。其值始终是 String?:

get("/users/{id}") {
    val id = call.parameters["id"] ?: return@get call.respondText("Missing id", status = HttpStatusCode.BadRequest)
    call.respondText("User: $id")
}

可选路径片段

在片段后添加 ?,即可将其标记为可选:{name?}。如果该片段缺失,call.parameters["name"] 会返回 null。

get("/posts/{slug?}") {
    val slug = call.parameters["slug"]
    if (slug == null) call.respondText("All posts")
    else call.respondText("Post: $slug")
}

类型化参数转换

使用 Parameters 上的扩展函数,将路径参数转换为指定类型的值。Ktor 提供了内置辅助函数,您也可以自行编写:

get("/items/{id}") {
    val id = call.parameters["id"]?.toLongOrNull()
        ?: return@get call.respond(HttpStatusCode.BadRequest, "Invalid id")
    call.respondText("Item #$id")
}

查询参数

通过 call.request.queryParameters["key"] 访问查询字符串参数。同一键对应的多个值可通过 getAll("key") 获取:

get("/search") {
    val q = call.request.queryParameters["q"] ?: ""
    val page = call.request.queryParameters["page"]?.toIntOrNull() ?: 1
    call.respondText("Search: $q, page $page")
}

路由分组

使用 route("/prefix") { ... },将相关路由归入共同前缀下。这样可以减少重复,并使路由树更易读:

route("/api/v1") {
    route("/users") {
        get { /* list users */ }
        get("/{id}") { /* get user by id */ }
        post { /* create user */ }
    }
}

在函数中组织路由

将路由组提取为 Route 上的扩展函数,使路由配置保持模块化:

fun Route.userRoutes() {
    route("/users") {
        get { /* ... */ }
        post { /* ... */ }
        get("/{id}") { /* ... */ }
    }
}

// In Application module:
routing { userRoutes() }

处理请求正文

以文本、字节或反序列化对象的形式接收请求正文(需要 ContentNegotiation 插件)。使用 call.receive() 进行类型化反序列化:

post("/users") {
    val user = call.receive<UserDto>()
    call.respond(HttpStatusCode.Created, user)
}

使用状态码进行响应

使用 call.respond(status, body) 进行完全控制,或使用便捷方法 call.respondText()、call.respondFile()、call.respond(HttpStatusCode.NotFound):

get("/users/{id}") {
    val user = userRepo.find(call.parameters["id"])
    if (user == null) call.respond(HttpStatusCode.NotFound)
    else call.respond(user)
}

通配符和尾部通配路由

使用 * 匹配单个通配符片段,使用 {...}(尾部通配符)将路径的其余部分作为单个参数进行匹配:

get("/static/{path...}") {
    val filePath = call.parameters.getAll("path")?.joinToString("/") ?: ""
    call.respondText("Serving: $filePath")
}

路由优先级

Ktor 按声明顺序评估路由。应在通配路由之前声明更具体的路由。当两条路由都匹配时,首个匹配项获胜。

快速检查

在 Ktor 中,如何将多条路由归入共同的 URL 前缀下?

回顾:路由与类型化参数

关键要点:

  • 在 routing { } 中使用 get、post 等定义路由
  • 路径参数:{name} — 通过 call.parameters["name"] 访问
  • 查询参数:call.request.queryParameters["key"]
  • 使用 route("/prefix") { } 对路由分组,并将其提取为 Route 上的扩展函数
  • 使用 call.receive() 接收类型化正文(需要 ContentNegotiation)

常见问题解答

「路由与类型化参数」课时是免费的吗?

是的 — 「路由与类型化参数」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Kotlin Academy 课程的其余内容,请升级到 CoddyKit PRO。 Kotlin Academy 课程共包含 4 节课。

「路由与类型化参数」这节课中我会学到什么?

使用路径参数和查询参数定义路由,并通过 route 代码块将它们分组。 你通过在浏览器中直接运行的动手代码来练习 Kotlin Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Kotlin Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Kotlin Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「路由与类型化参数」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Kotlin Academy 课中编写并运行代码吗?

能。每节 Kotlin Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. Ktor 项目设置:embeddedServer 与 Application 模块
  2. 路由与类型化参数
  3. 内容协商与 kotlinx.serialization
  4. 身份验证插件:JWT 与会话
← 返回 Kotlin Academy