如何在 Spring 6 和 Spring Boot 3 中的新 HTTP 接口中重试

问题描述 投票:0回答:1

Spring引入了新的HTTP接口。对于异常处理文档指出要注册一个响应状态处理程序,该处理程序适用于通过客户端执行的所有响应:

WebClient webClient = WebClient.builder()
    .defaultStatusHandler(HttpStatusCode::isError, resp -> ...)
    .build();

但是,尚不清楚如何处理重试。

在 WebClient 中,您可以简单地使用 retryWhen():

public Mono<String> getData(String stockId) {
return webClient.get()
  .uri(PATH_BY_ID, stockId)
  .retrieve()
  .bodyToMono(String.class)
  .retryWhen(Retry.backoff(3, Duration.ofSeconds(2)));
}

我不确定如何将重试与 Http 接口结合起来。

java spring spring-boot spring-webclient
1个回答
5
投票

我想通了。您需要使用交换过滤器。我针对不同的问题实现了类似的解决方案:添加重试 WebClient 的所有请求

 @Bean
  TodoClient todoClient() {
    WebClient webClient =
        WebClient.builder()
            .baseUrl("sampleUrl")
            .filter(retryFilter())
            .build();
    HttpServiceProxyFactory factory =
        HttpServiceProxyFactory.builder(WebClientAdapter.forClient(webClient)).build();
    return factory.createClient(TodoClient.class);
  }

  
private ExchangeFilterFunction retryFilter() {
     return (request, next) ->
         next.exchange(request)
               .flatMap(
            clientResponse ->
                Mono.just(clientResponse)
                    .filter(response -> clientResponse.statusCode().isError())
                    .flatMap(ClientResponse::createException)
                    .flatMap(Mono::error)
                    .thenReturn(clientResponse))
             .retryWhen(
                         Retry.fixedDelay(3, Duration.ofSeconds(30))
             .doAfterRetry(retrySignal -> log.warn("Retrying"));
      };
  }
© www.soinside.com 2019 - 2024. All rights reserved.