当前位置: 首页 > 知识库问答 >
问题:

WebClient-如何忽略特定HTTP错误

柯昱
2023-03-14

我想创建一个SpringWebClient,它忽略一个特定的HTTP错误。来自WebClient的文档。检索():

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

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

我能想到的最好的办法是:

        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从未被调用)。

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

共有2个答案

孟茂学
2023-03-14

在对spring webflux 5.3.4进行广泛调试之后,在Martin Tarjányi的一些想法的帮助下,我将此作为唯一可能的“解决方案”:

WebClient webClient = WebClient.builder().filter((request, next) -> {
    return next.exchange(request).flatMap(res -> {
        if (res.rawStatusCode() == HttpStatus.I_AM_A_TEAPOT.value()) {
            res = res.mutate().rawStatusCode(299).build();
        }
        return Mono.just(res);
    });
}).build();

URI uri = UriComponentsBuilder.fromUriString("https://httpstat.us/418").build().toUri();
String body = webClient.get().uri(uri).retrieve().toEntity(String.class).block().getBody();

背景:我正在将一些代码从RestTemplate迁移到WebClient。旧代码如下所示:

RestTemplate restTemplate = ...;
restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
    @Override
    public void handleError(ClientHttpResponse response) throws IOException {
        if (response.getRawStatusCode() == HttpStatus.I_AM_A_TEAPOT.value()) {
            return;
        }
        super.handleError(response);
    }
});

URI uri = UriComponentsBuilder.fromUriString("https://httpstat.us/418").build().toUri();
String body = restTemplate.getForEntity(uri, String.class).getBody();

我相信这是一个简单而常见的情况。

WebClient还不是RestTemplate的100%替代品。

东方涛
2023-03-14

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

未调用lambda的原因是响应。OneRorResume创建一个全新的Mono,您的代码不使用结果(即,它没有分配给响应变量),因此最终返回一个没有OneRorResume运算符的Mono

使用Project Reactor时,通常最好避免声明局部MonoFlux变量,而是使用单链。这有助于避免类似的细微错误。

WebClient webClient = WebClient.builder()
        .filter((request, next) -> next.exchange(request)
                        .onErrorResume(WebClientResponseException.class, ex -> ex.getRawStatusCode() == 418 ? Mono.empty() : Mono.error(ex)))
        .build();
 类似资料:
  • QueryList遵循将业务与错误分离的原则, HTTP请求传输过程中如果出现的错误,QueryList将会抛出异常。 QueryList的HTTP客户端基于GuzzleHttp,它提供了丰富的HTTP异常类型,用户可以自行设计根据不同的异常类型做不同的处理。 如果你觉得麻烦,并不想每次都去处理HTTP异常,选择直接忽略,让程序继续运行下去,做法可以参考下面方式: 对内置的get()进行封装: u

  • 问题内容: 我正在使用以下选项 在bash脚本中停止执行错误。我有大约100行脚本正在执行,并且我不想检查脚本中每一行的返回码。 但是对于一个特定的命令,我想忽略该错误。我怎样才能做到这一点? 问题答案: 解决方案: 例: 将永远不会打印。 另外,我想补充一点,当打开时,如果管道中的命令之一具有非零退出代码(关闭该命令必须是最后一个),shell认为整个管道具有非零退出代码就足够了。

  • 使用ESLint是否可以忽略整个目录的一个特定规则? 在我的例子中,我想忽略为一个名为的目录

  • 我试图爬过craiglist的论坛类别。组织机构(https://forums.craigslist.org/).我的蜘蛛: 我通过错误回调收到以下消息: [失败实例:Traceback:: /usr/local/lib/python2.7/site-packages/twisted/internet/defer.py: 455:回调 /usr/local/lib/python2.7/site-p

  • 像这种类型错误,发现是因为扩展版本的问题导致的错误,打算不去修复,想进行忽略,但是发现像 <!-- @ts-ignore --> 这样的注释没效果,这个怎么办好?