如何让响应式 Webclient 跟随 3XX 重定向?

37

我已经创建了一个基本的REST控制器,使用Spring-boot 2中的reactive Webclient和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);
    }

}
当我收到一个 3XX 响应代码时,我希望 web 客户端可以使用响应中的 Location 跟随重定向,并递归调用该 URI,直到我得到非 3XX 响应。
我实际得到的结果是 3XX 响应。

1
我已在Jira中创建了一个问题:https://jira.spring.io/browse/SPR-16277 - Martin Österlund
有没有解决办法?似乎Spring Boot 2在GA发布版仍无法跟随重定向。 - Sven
1
修复(https://github.com/reactor/reactor-netty/issues/235)已经在 netty 0.8 中,该版本将包含在 Spring 5.1 中。 - Martin Österlund
我最好找一些丑陋的老派编码,直到今年晚些时候。5.1还有很长时间。 - Sven
2个回答

58

根据文档,您需要配置客户端。

           WebClient.builder()
                    .clientConnector(new ReactorClientHttpConnector(
                            HttpClient.create().followRedirect(true)
                    ))

谢谢,这些文档是不完整的,似乎没有涵盖所有内容。这有助于填补空白! - Dave Jensen
ReactorClientHttpConnector 的默认构造函数会在 HttpClient 中添加 compress=true。如果我们想保持一致的客户端初始化,可以改为:HttpClient.create().compress(true).followRedirect(true) - Triphon Penakov
我该如何获取最终的URL? - Vladimir

9
你可以将函数的URL参数化,并在获取3XX响应时进行递归调用。实现类似于以下示例(在实际实现中,你可能想限制重定向的数量):
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);
            }

这就是我们最终得到的东西。看起来 Spring Boot 2.1.0 推迟了,所以我们会使用这个解决方案一段时间。 - Sven

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接