如何在错误 Spring WebFlux 上调用另一个 api

Posted

技术标签:

【中文标题】如何在错误 Spring WebFlux 上调用另一个 api【英文标题】:How to call another api on error Spring WebFlux 【发布时间】:2020-11-12 03:19:09 【问题描述】:

我学习WebFlux不是太多,但是我发现了一个我无法解决的任务。如果我当前的请求中出现超时错误,我应该调用另一个 API,并且如果这个 API 返回正常 - 我应该离开这个方法并继续执行我的应用程序。我写了一些代码,但我没有找到解决方案。

        return WebClient.create(documentLocalUrlSettings.getBase())
        .post()
        .uri(documentLocalUrlSettings.getSend())
        .body(BodyInserters.fromValue(sendRequestDto))
        .headers(httpHeadersConsumer)
        .retrieve()
        .bodyToMono(SendAndStatusResponseDto.class)
        .timeout(Duration.ofMillis(10000))
        .retryWhen(errorCurrentAttempt -> errorCurrentAttempt
            .flatMap(tp -> 

                var status = WebClient.create("baseUrl")
                    .post()
                    .uri("callableServiceUrl")
                    .body(BodyInserters.fromValue(StatusRequestDto.class))
                    .retrieve();

                if (status != null && status.getResult().getResultCode() == 10001) 
                    return; 
                 else 
                    return Mono.<Object>error(new InternalRuntimeException(InternalExceptionCode.EX1001));  
                
            )).block();

UPD:api 调用 - 同步

【问题讨论】:

【参考方案1】:

您应该阅读retryWhen() 操作员文档,因为它没有达到您的预期。而不是使用retryWhen(),您应该使用运算符doOnError(),它采用带有从MonoFlux 操作发出的错误参数的函数,并返回新的MonoFlux 发出新行为的值。

你应该这样做:

.timeout(Duration.ofMillis(10000))
.doOnError(error ->
    (error instanceof TimeoutException) 
        ? (/** call API here returning Mono **/) 
        : Mono.error(error)
).continueProcessingHere()

还要注意.block() 方法不适合在使用 Webflux 时调用。您正在使用的Webclient 已经是响应式的,因此您不需要阻止结果,而是使用您从中获得的MonoFlux 并使用map()flatMap()onError() 处理结果代码等等运营商的。

【讨论】:

doOnError 接受消费者而不是函数。返回 void 的含义

以上是关于如何在错误 Spring WebFlux 上调用另一个 api的主要内容,如果未能解决你的问题,请参考以下文章

从一个微服务到另一个微服务的 WebClient 构建器调用在 Webflux 中首次出现错误的请求错误

如何模拟 Spring WebFlux WebClient?

从另一个 API 端点动态触发现有 Flux - Spring Webflux

如何在 Spring Webflux / Reactor Netty Web 应用程序中执行阻塞调用

反应式编程:Spring WebFlux:如何构建微服务调用链?

Spring WebFlux WebClient - 如何解决 400 错误请求