Spring Boot 2.2.6 Kotlin协程:空Mono返回404响应实现
问题解决方案:Spring Boot Kotlin协程REST API处理空结果返回404
我正在使用Spring Boot 2.2.6、Kotlin和协程实现一个简单的响应式REST API,尝试采用函数式风格。当仓库返回空Mono
(Task为自定义领域模型类)时,如何修改以下代码以返回404 HTTP响应?注意我使用了协程,需要Flow实例,常规示例不适用。代码如下: suspend fun findOne(request: ServerRequest): ServerResponse { val id = request.pathVariable("id") val task = repository.findById(id) return ServerResponse .ok() .json() .bodyAndAwait(task.asFlow()) }
核心思路
因为你用了Kotlin协程,我们可以利用挂起函数的特性来同步处理Mono的空值情况,而不是依赖Reactor的链式调用。关键是把Mono<Task>转换为可空的Task?对象,再根据是否为空返回对应的HTTP响应。
修改后的代码
suspend fun findOne(request: ServerRequest): ServerResponse { val id = request.pathVariable("id") // 使用awaitSingleOrNull()将Mono转为挂起函数的可空返回值 val task = repository.findById(id).awaitSingleOrNull() return task?.let { // Task存在时,返回200和对应的Flow ServerResponse.ok() .json() .bodyAndAwait(it.asFlow()) } ?: run { // Task不存在时,返回404响应 ServerResponse.notFound().buildAndAwait() } }
代码解释
awaitSingleOrNull(): 这是Reactor-Kotlin扩展库提供的挂起函数,作用是等待Mono发出元素。如果Mono是空的(没有元素),它会返回null,完美适配我们的空值判断需求。- Kotlin分支处理: 用
let和Elvis运算符(?:)实现简洁的分支逻辑:- 当
task不为空时,构建200响应并把Task转为Flow返回。 - 当
task为空时,调用buildAndAwait()构建并返回404响应(因为我们在suspend函数里,必须用挂起版本的构建方法)。
- 当
扩展:如果仓库直接返回Flow
如果你的Repository是直接返回Flow<Task>而不是Mono<Task>,逻辑类似,只需要用firstOrNull()获取第一个元素(或null):
suspend fun findOne(request: ServerRequest): ServerResponse { val id = request.pathVariable("id") val task = repository.findById(id).firstOrNull() return task?.let { ServerResponse.ok() .json() .bodyAndAwait(flowOf(it)) } ?: ServerResponse.notFound().buildAndAwait() }
依赖检查
确保你的项目中已经引入了Reactor-Kotlin的扩展依赖(Spring Boot 2.2.6通常会自动包含,但如果没有的话,需要手动添加):
Gradle(Kotlin DSL)
implementation("io.projectreactor.kotlin:reactor-kotlin-extensions") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
Maven
<dependency> <groupId>io.projectreactor.kotlin</groupId> <artifactId>reactor-kotlin-extensions</artifactId> </dependency> <dependency> <groupId>org.jetbrains.kotlinx</groupId> <artifactId>kotlinx-coroutines-reactor</artifactId> </dependency>
内容的提问来源于stack exchange,提问作者riccardo.cardin
相关产品推荐
相关产品推荐

