1

Spring has introduced the new HTTP interface. For exception handling the documentation states to register a response status handler that applies to all responses performed through the client:

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

However, it's not clear how to handle retries.

In WebClient you could simple use 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)));
}

I'm not sure how to incorporate retries with the Http interfaces.

pooya72
  • 1,003
  • 9
  • 15

1 Answers1

2

I figured it out. You need to use an exchange filter. I implemented a similiar solution for a different problem: Adding a retry all requests of 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)
             .retryWhen(
                         Retry.fixedDelay(3, Duration.ofSeconds(30))
             .doAfterRetry(retrySignal -> log.warn("Retrying"));
      };
  }
pooya72
  • 1,003
  • 9
  • 15
  • As it's posted it's not working. `ExchangeFilterFunction.filter` returns a `Mono`, but your lambda returns nothing. However, adding the return is not making the code work with HTTP Interfaces either. – zyexal Dec 28 '22 at 00:55