xBentu
xBentu

Reputation: 41

Adding new header when retrying with Spring WebClient

webclientbuilder.baseUrl(url)
                .defaultHeaders(headers -> headers.addAll(requestHeader))
                .build()
                .post()
                .uri("/uri")
                .bodyValue(data)
                .exchange()
                .flatMap(response  -> {
                                if(response.statusCode() == HttpStatus.UNAUTHORIZED){
                                                //retry with updated token in header
                                }
                })
                //return bodyToMono of specific object when retry is done or if
                //response status is 2xx

Any advice on how to deal with this is appreciated! As the comments say, I need to add the new token to the header before I retry the post request if there is a statusCode of UNAUTHORIZED, and if statusCode of 2xx, then return bodyToMono.

Upvotes: 3

Views: 3122

Answers (1)

Andrei
Andrei

Reputation: 143

You can solve this by adding a filter to your webclient:

public ExchangeFilterFunction retryOn401() {
    return (request, next) -> next.exchange(request)
            .flatMap((Function<ClientResponse, Mono<ClientResponse>>) clientResponse -> {
                if (clientResponse.statusCode() == HttpStatus.UNAUTHORIZED) {
                    return authClient.getUpdatedToken() //here you get a Mono with a new & valid token
                            .map(token -> ClientRequest
                                    .from(request)
                                    .headers(headers -> headers.replace("Authorization", Collections.singletonList("Bearer " + token)))
                                    .build())
                            .flatMap(next::exchange);
                } else {
                    return Mono.just(clientResponse);
                }
            });
}

Hence, when the webclient retries the unauthorized request, it can obtain a new token and set it on the header before performing the retry. Make sure to add it to the webclient:

webclientbuilder.baseUrl(url)
            .defaultHeaders(headers -> headers.addAll(requestHeader))
            .filter(retryOn401())
            .build();

Upvotes: 8

Related Questions