代码之家  ›  专栏  ›  技术社区  ›  SledgeHammer

如何正确构造此webClient调用?

  •  0
  • SledgeHammer  · 技术社区  · 4 年前

    我有一个方法,目前看起来像这样:

    protected void doHealthCheck(Health.Builder builder) {
        try {
            VaultHealth vaultHealth = this.webClient
                .get()
                .exchange()
                    .block()
                        .bodyToMono(VaultHealth.class)
                            .block();
    
            if (vaultHealth.isInitialized() && !vaultHealth.isSealed() && !vaultHealth.isStandby()) {
                builder.up();
                return;
            }
        }
        catch (Exception e) {
            builder.down();
            return;
        }
    
        builder.down();
    }
    

    我的理解是这是错误的。所以现在我正在考虑修复它,它应该是这样的:

            this.webClient
                .get()
                .exchange()
                    .doOnSuccess(???)
                    .doOnError(Health.Builder::down);
    

    doOnSuccess将返回一个ClientResponse,我需要在调用Health之前检查响应中的内容。建设者:起来。

    如果我打电话。flatMap()而不是doOnSuccess,它会引发错误吗?还是我需要把它放在doOnSuccess里面?如果我把它放在doOnSuccess中,似乎我需要进行双重doOnSuccess(这不可能是对的,是吗?):

    .doOnSuccess(x -> x.bodyToMono(VaultHealth.class).doOnSuccess(y -> if (y...) builder.up())
    

    此外,我假设如果我以这种方式重新构造它,我不需要try/catch,因为doon错误可以处理这个问题?

    虽然这个特殊的方法在操作完成后执行操作是有意义的,但是在我需要返回对象的情况下呢?我的另一个理解是,我永远不应该使用。布洛克,对吗?

    0 回复  |  直到 4 年前
        1
  •  1
  •   K.Nicholas    4 年前

    Mono::flatMap 是为了 asynchronous 操作。对WebClient的调用是一种“异步”操作,因此通常需要使用 Mono:flatMap 之后 WebClient::exchange 方法不,你不应该使用 Mono::block 在“WebFlux”应用程序中。用被动的方式,而不是你所拥有的:

        public void run(ApplicationArguments args) throws Exception {
            Health.Builder healthBuilder = new Health.Builder();
            healthBuilder.down();
            doHealthCheck(healthBuilder).onErrorReturn(healthBuilder).map(Health.Builder::build).subscribe(System.out::println);
        }
        protected Mono<Health.Builder> doHealthCheck( Health.Builder builder) {
            return webClient
                .get()
                .retrieve()
                .bodyToMono(VaultHealth.class)
                .map(vaultHealth->{
                    if (vaultHealth.isInitialized() && !vaultHealth.isSealed() && !vaultHealth.isStandby())
                        builder.up();
                    else 
                        builder.down();
                    return builder;
                });
        }