首页 > 解决方案 > 如何在 Spring 的服务调用中获取 Mono QS 参数值

问题描述

我对 Reactive 还很陌生,所以在范式转变方面有点挣扎,但也许有人可以帮助我克服这个问题?

我的控制器将 Mono(称为“限制”)作为服务参数传递给我的服务。Mono 在订阅时发出一个整数,服务用于完成其工作,它返回一个 Flux。

在我的服务方法中,我需要订阅单声道 - 但我需要在我的服务方法(它使 Web 客户端 REST 调用到某个其他端点)“之前”这样做,因为在 REST 调用中需要限制值。现在,我知道订阅将在某个时候完成,但在主线程继续完成该方法后它正在完成。我的代码:

public Flux<User> getUserdata(Mono<Integer> limit) {

        return
                Flux.from(WebClient.create()
                        .get()
                        .uri(uriBase, uri -> {
                            uri.queryParam("_limit", limit.subscribe(k -> String.valueOf(k)));
                        })
                        .accept(MediaType.APPLICATION_JSON)
                        .retrieve()
                        .bodyToFlux(User.class));
}

如果我对限制参数进行硬编码,则可以。我需要确保订阅完成的人。我知道我仍然有点混淆同步/异步,所以关于如何反应/正确地做到这一点的任何想法/建议?

TIA,

彼得

标签: springreactive-programmingspring-webflux

解决方案


Mono并且FluxProducers。那个subscribing叫做Consumer. 在您的情况下,决赛Consumer可能是发起呼叫的人。很可能是网页或其他调用您的服务的服务。

我要说的是,既然你producer最有可能不应该跟注subscribe,因为你不是决赛选手consumer。一旦您看到自己这样做,您就可以说这是代码异味。

我已经用一些评论重写了您在下面提供的示例。

public Flux<User> getUserdata(Mono<Integer> limit) {

    // Should be created in a @Configuration annotated, as a 
    // @Bean WebClient is quite a large class and can affect performance.
    final WebClient webclient = WebClient.create();

    // We flatMap incoming mono to get the value, and then
    // call webClient, bodyToFlux returns a Flux for us.
    return limit.flatMap(l -> webClient.get()
                        .uri(uriBase, uri -> {
                            uri.queryParam("_limit", String.valueOf(l))
                               .build());
                        })
                        .accept(MediaType.APPLICATION_JSON)
                        .retrieve()
                        .bodyToFlux(User.class));
}

推荐阅读