Spring WebClient-如何处理错误情况

问题描述 投票:1回答:1

我们正在将org.springframework.web.reactive.function.client.WebClientreactor.netty.http.client.HttpClient作为Spring 5.1.9的一部分,使用exchange()方法发出请求。此方法的documentation突出显示以下内容:

...使用exchange()时,这是应用程序的责任消耗任何响应内容,而不考虑场景(成功,错误,意外数据等)。否则会导致内存泄漏。

我们对exchange()的使用是相当基本的,但是错误场景的文档对我来说并不明确,我想确定我们已经为所有结果正确释放了资源。本质上,我们有一个阻塞实现,该实现发出一个请求并返回ResponseEntity,而不管响应代码如何:

    try {
        ...
        ClientResponse resp = client.method(method).uri(uri).syncBody(body).exchange().block();
        ResponseEntity<String> entity =  resp.toEntity(String.class).block();
        return entity;
    } catch (Exception e) {
        // log error details, return internal server error
    }

[如果我了解实现方法,则无论响应代码如何(例如4xx,5xx),如果成功分派了请求,exchange()都会始终给我们答复。在这种情况下,我们只需要调用toEntity()即可使用响应。我担心的是错误情况(例如无响应,低级别的连接错误等)。上面的异常处理是否可以捕获所有其他场景,并且它们中的任何一个都有需要使用的响应吗?

注意:ClientResponse.releaseBody()仅在5.2中引入

java spring reactor spring-webclient
1个回答
0
投票

发出请求时必须使用响应,但是如果您不能执行请求,则可能在之前引发了异常,并且响应不会有问题。

在文档中说:

注意:通过WebClient exchange()方法使用ClientResponse时,必须使用以下方法之一来确保主体已被消耗或释放:

  1. body(BodyExtractor)
  2. bodyToMono(Class)或bodyToMono(ParameterizedTypeReference)
  3. bodyToFlux(Class)或bodyToFlux(ParameterizedTypeReference)
  4. toEntity(Class)或toEntity(ParameterizedTypeReference)
  5. toEntityList(Class)或toEntityList(ParameterizedTypeReference)
  6. toBodilessEntity()
  7. releaseBody()

如果没有期望的响应内容,也可以使用bodyToMono(Void.class)。但是请记住,如果有任何内容到达,连接将被关闭,而不是放回池中。这与releaseBody()的确相反,后者确实消耗了整个主体并释放了接收到的所有内容。

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/reactive/function/client/ClientResponse.html

您可以尝试使用.retrieve()代替.exchange()并根据自己的喜好处理错误。

  public Mono<String> someMethod() {

    return webClient.method(method)
      .uri(uri)
      .retrieve()
      .onStatus(
        (HttpStatus::isError), // or the code that you want
        (it -> handleError(it.statusCode().getReasonPhrase())) //handling error request
      )
      .bodyToMono(String.class);


  }

  private Mono<? extends Throwable> handleError(String message) {
    log.error(message);
    return Mono.error(Exception::new);
  }

在此示例中,我使用了Exception,但是您可以创建一些更具体的异常,然后使用某些异常处理程序返回所需的http状态。不建议使用块,更好的方法是将流向前传递。

© www.soinside.com 2019 - 2024. All rights reserved.