Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make reactive webclient follow 3XX-redirects?

I have created a basic REST controller which makes requests using the reactive Webclient in Spring-boot 2 using netty.

@RestController
@RequestMapping("/test")
@Log4j2
public class TestController {

    private WebClient client;

    @PostConstruct
    public void setup() {

        client = WebClient.builder()
                .baseUrl("http://www.google.com/")
                .exchangeStrategies(ExchangeStrategies.withDefaults())
                .build();
    }


    @GetMapping
    public Mono<String> hello() throws URISyntaxException {
        return client.get().retrieve().bodyToMono(String.class);
    }

}

When I get a 3XX response code back I want the webclient to follow the redirect using the Location in the response and call that URI recursively until I get a non 3XX response.

The actual result I get is the 3XX response.

like image 561
Martin Österlund Avatar asked Dec 05 '17 14:12

Martin Österlund


People also ask

Is WebClient reactive?

WebClient is a non-blocking, reactive client for performing HTTP requests with Reactive Streams back pressure. WebClient provides a functional API that takes advantage of Java 8 Lambdas.

Is WebClient asynchronous?

On the other side, WebClient uses an asynchronous, non-blocking solution provided by the Spring Reactive framework.

How do you get a response from WebClient?

First, let's make the GET call with WebClient. get and use a Mono of type Object[] to collect the response: Mono<Object[]> response = webClient. get() .

How do I log a body response in WebClient?

Logging Request and Response with Body HTTP clients have features to log the bodies of requests and responses. Thus, to achieve the goal, we are going to use a log-enabled HTTP client with our WebClient. We can do this by manually setting WebClient. Builder#clientConnector – let's see with Jetty and Netty HTTP clients.


2 Answers

You need to configure the client per the docs

           WebClient.builder()
                    .clientConnector(new ReactorClientHttpConnector(
                            HttpClient.create().followRedirect(true)
                    ))
like image 121
Adam Bickford Avatar answered Oct 18 '22 01:10

Adam Bickford


You could make the URL parameter of your function, and recursively call it while you're getting 3XX responses. Something like this (in real implementation you would probably want to limit the number of redirects):

public Mono<String> hello(String uri) throws URISyntaxException {
    return client.get()
            .uri(uri)
            .exchange()
            .flatMap(response -> {
                if (response.statusCode().is3xxRedirection()) {
                    String redirectUrl = response.headers().header("Location").get(0);
                    return response.bodyToMono(Void.class).then(hello(redirectUrl));
                }
                return response.bodyToMono(String.class);
            }
like image 8
Andrija Kovačević Avatar answered Oct 17 '22 23:10

Andrija Kovačević