首页 > 解决方案 > WebClient - 如何忽略特定的 HTTP 错误

问题描述

我想创建一个忽略特定 HTTP 错误的 Spring WebClient。从 WebClient.retrieve() 的文档中:

默认情况下,4xx 和 5xx 响应会导致 WebClientResponseException。要自定义错误处理,请使用 ResponseSpec.onStatus(Predicate, Function) 处理程序。

我希望通过 WebClient 实例的所有调用都忽略特定的 HTTP 错误。这就是为什么 onStatus() 对我没有用(必须根据响应设置)。

我能想到的最好的是:

        WebClient webClient = WebClient.builder().filter((request, next) -> {
            Mono<ClientResponse> response = next.exchange(request);
            response = response.onErrorResume(WebClientResponseException.class, ex -> {
                return ex.getRawStatusCode() == 418 ? Mono.empty() : Mono.error(ex);
            });
            return response;
        }).build();

        URI uri = UriComponentsBuilder.fromUriString("https://httpstat.us/418").build().toUri();
        webClient.get().uri(uri).retrieve().toBodilessEntity().block();

但它确实抛出异常而不是忽略它(传递给 onErrorResume() 的 lambda 永远不会被调用)。

编辑:修复了第一个答案指出的错误。

标签: spring-webflux

解决方案


更新:原来这个答案并没有解决过滤掉特定状态代码的核心问题,只是解决了一般的编码模式。


没有调用 lambda的原因onErrorResume是它response.onErrorResume创建了一个全新的Mono并且您的代码不使用结果(即它没有分配给response变量),因此最终返回了Mono没有onErrorResume运算符的 a。

使用 Project Reactor 通常避免声明局部变量和变量并使用单个链是一个好Mono习惯Flux。这有助于避免类似的细微错误。

WebClient webClient = WebClient.builder()
        .filter((request, next) -> next.exchange(request)
                        .onErrorResume(WebClientResponseException.class, ex -> ex.getRawStatusCode() == 418 ? Mono.empty() : Mono.error(ex)))
        .build();

推荐阅读