WebFlux功能:如何检测空Flux并返回404?

Jue*_*ann 7 spring kotlin spring-boot project-reactor spring-webflux

我有以下简化的处理函数(Spring WebFlux和使用Kotlin的函数API).但是,当Flux为空时,我需要提示如何检测空Flux然后对404使用noContent().

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)
}
Run Code Online (Sandbox Code Playgroud)

Bri*_*zel 18

来自Mono:

return customerMono
           .flatMap(c -> ok().body(BodyInserters.fromObject(c)))
           .switchIfEmpty(notFound().build());
Run Code Online (Sandbox Code Playgroud)

来自Flux:

return customerFlux
           .collectList()
           .flatMap(l -> {
               if(l.isEmpty()) {
                 return notFound().build();

               }
               else {
                 return ok().body(BodyInserters.fromObject(l)));
               }
           });
Run Code Online (Sandbox Code Playgroud)

请注意,collectList缓冲内存中的数据,因此这可能不是大列表的最佳选择.可能有更好的方法来解决这个问题.


RJ.*_*ang 8

使用Flux.hasElements() : Mono<Boolean>功能:

return customerFlux.hasElements()
                   .flatMap {
                     if (it) ok().body(customerFlux)
                     else noContent().build()
                   }
Run Code Online (Sandbox Code Playgroud)


zen*_*non 6

除了Brian的解决方案,如果您不想一直对列表进行空检查,您可以创建一个扩展函数:

fun <R> Flux<R>.collectListOrEmpty(): Mono<List<R>> = this.collectList().flatMap {
        val result = if (it.isEmpty()) {
            Mono.empty()
        } else {
            Mono.just(it)
        }
        result
    }
Run Code Online (Sandbox Code Playgroud)

并像您为 Mono 那样称呼它:

return customerFlux().collectListOrEmpty()
                     .switchIfEmpty(notFound().build())
                     .flatMap(c -> ok().body(BodyInserters.fromObject(c)))
Run Code Online (Sandbox Code Playgroud)


ayu*_*har 6

我不知道为什么没有人谈论使用 Flux.java 的 hasElements() 函数,它会返回一个 Mono。