我正在使用 WebFlux 框架开发带有 Spring Boot 2.0 和 Kotlin 的应用程序。
我想在保存交易之前检查用户 ID 是否存在。我陷入了一个简单的事情,比如验证 Mono 是否为空。
fun createTransaction(serverRequest: ServerRequest) : Mono<ServerResponse> {
val transaction = serverRequest.body(BodyExtractors.toMono(Transaction::class.java))
transaction.flatMap {
val user = userRepository.findById(it.userId)
// If it's empty, return badRequest()
}
return transaction.flatMap { transactionRepository.save(it).then(created(URI.create("/transaction/" + it.id)).build()) }
}
有可能做我想做的事吗?
原文由 voliveira89 发布,翻译遵循 CC BY-SA 4.0 许可协议
允许检查
Flux
/Mono
是否为空的技术使用运算符
.switchIfEmpty
/.defaultIfEmpty
/Mono.repeatWhenEmpty
使用提到的运算符,您将能够在 Stream 完成时对情况做出反应,而无需发出任何元素。
First of all, remember that operators such
.map
,.flatMap
,.filter
and many others will not be invoked at all if there noonNext
已被调用。这意味着在您的情况下,下一个代码根本不会被调用,如果
transaction
为空。如果需要在流程为空时处理情况,则应按以下方式考虑像 next 这样的运算符:
实际解决方案
另外,我注意到您从主
transaction
创建了两个子流。实际上,下面的代码根本不会执行:并且只会执行从方法返回的最后一个。发生这种情况是因为您没有使用 operator
.subscribe(...)
进行订阅。第二点,您不能一次订阅同一个请求主体(对
WebClient
的响应的一种限制)。因此,您需要以下一种方式共享您的请求正文,因此完整的示例将是:或者更简单的情况,不共享事务流但使用
Tuple
: