37

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.

Brian Clozel
  • 56,583
  • 15
  • 167
  • 176
Martin Österlund
  • 473
  • 1
  • 5
  • 7

2 Answers2

56

You need to configure the client per the docs

           WebClient.builder()
                    .clientConnector(new ReactorClientHttpConnector(
                            HttpClient.create().followRedirect(true)
                    ))
Adam Bickford
  • 1,216
  • 12
  • 14
  • Thanks, the docs are incomplete and don't appear to go over everything. This helps fill in the gaps! – Dave Jensen Nov 25 '19 at 03:21
  • Default constructor of the `ReactorClientHttpConnector` add `compress=true` to the HttpClient. If we want to be consistent client initialization can be changed to: `HttpClient.create().compress(true).followRedirect(true)` – Triphon Penakov Jan 31 '22 at 06:34
  • And how do I get the final URL? – Vladimir Jun 05 '22 at 17:14
9

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);
            }
  • This is somewhat what we ended up with. Seems Spring Boot 2.1.0 is delayed so we'll be using this solution for a while. – Sven Jun 30 '18 at 13:51