WebFlux 功能:如何检测空 Flux 并返回 404?
Posted
技术标签:
【中文标题】WebFlux 功能:如何检测空 Flux 并返回 404?【英文标题】:WebFlux functional: How to detect an empty Flux and return 404? 【发布时间】:2018-02-04 19:50:54 【问题描述】:我有以下简化的处理函数(Spring WebFlux 和使用 Kotlin 的函数式 API)。但是,我需要提示如何检测空的 Flux,然后在 Flux 为空时使用 noContent() 处理 404。
fun findByLastname(request: ServerRequest): Mono<ServerResponse>
val lastnameOpt = request.queryParam("lastname")
val customerFlux = if (lastnameOpt.isPresent)
service.findByLastname(lastnameOpt.get())
else
service.findAll()
// How can I detect an empty Flux and then invoke noContent() ?
return ok().body(customerFlux, Customer::class.java)
【问题讨论】:
【参考方案1】:使用Flux.hasElements() : Mono<Boolean>
函数:
return customerFlux.hasElements()
.flatMap
if (it) ok().body(customerFlux)
else noContent().build()
【讨论】:
【参考方案2】:我不确定为什么没有人谈论使用 Flux.java 的 hasElements() 函数,它会返回一个 Mono。
【讨论】:
【参考方案3】:除了Brian的解决方案,如果你不想一直对列表做空检查,你可以创建一个扩展函数:
fun <R> Flux<R>.collectListOrEmpty(): Mono<List<R>> = this.collectList().flatMap
val result = if (it.isEmpty())
Mono.empty()
else
Mono.just(it)
result
并像在 Mono 中那样调用它:
return customerFlux().collectListOrEmpty()
.switchIfEmpty(notFound().build())
.flatMap(c -> ok().body(BodyInserters.fromObject(c)))
【讨论】:
【参考方案4】:来自Mono
:
return customerMono
.flatMap(c -> ok().body(BodyInserters.fromObject(c)))
.switchIfEmpty(notFound().build());
来自Flux
:
return customerFlux
.collectList()
.flatMap(l ->
if(l.isEmpty())
return notFound().build();
else
return ok().body(BodyInserters.fromObject(l)));
);
请注意,collectList
在内存中缓冲数据,因此这可能不是大型列表的最佳选择。可能有更好的方法来解决这个问题。
【讨论】:
修改后的变体也不起作用。当原始 Flux 为空时,customerFlux.collectList()
导致 Mono 包含一个空列表。因此,Mono 不为空(因为它包含一个空列表)并调用了 ok()。
找到解决方案。在flatMap()
内部需要一个if 语句:if (l.isEmpty()) notFound()... else ok()...
然后switchIfEmpty(...)
在此处已过时。
这仍然是在空 Flux
上返回 404 的最佳方式吗?以上是关于WebFlux 功能:如何检测空 Flux 并返回 404?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Webflux 中返回 Mono<Map<String, Flux<Integer>>> 响应?
Spring WebFlux,单元测试 Mono 和 Flux