在 Spring WebFlux 中处理全局场景

Handling Global Scenarios in Spring WebFlux

我有一个 Rest Web 客户端要执行 API 调用,我会按以下方式处理异常。

我想以全局方式处理 404、401 和 400 错误,而不是在单个客户端级别处理。我们怎样才能达到同样的效果。

public Mono<ProductResponse> getProductInformation(String productId) {
        return webClient.get()
                .uri("/v1/products/"+productId)
                .accept(MediaType.APPLICATION_JSON)
                .retrieve()
                .onStatus( httpStatus -> HttpStatus.NOT_FOUND.equals(httpStatus), clientResponse -> {
                    Mono<NotFound> notFound = clientResponse.bodyToMono(NotFound.class);
                    return notFound.flatMap( msg -> {
                        log.info(" Error Message {}" , msg.getErrorMsg());
                        return Mono.error(new NotFoundException(msg.getErrorMsg()));
                    });
                }).onStatus( httpStatus -> HttpStatus.UNAUTHORIZED.equals(httpStatus), clientResponse -> {
                    Mono<NotFound> notFound = clientResponse.bodyToMono(NotFound.class);
                   return Mono.error(new NotAuthorisedException("Unauthorised"));
                }).bodyToMono(ProductResponse.class);
    }

两种方法:

  1. 网络客户端的异常都包含在 WebClientResponseException class 中。您可以像这样使用 Spring 的 ExceptionHandler 注释来处理它。
  @ExceptionHandler(WebClientResponseException.class)
  public ResponseEntity handleWebClientException(WebClientResponseException ex){
    return ResponseEntity.badRequest().body(ex.getResponseBodyAsString());
  }

注意 - 您可以在此处根据响应状态编写复杂的条件逻辑,方法是使用 getStatusCode()getRawStatusCode()[=33= 等方法]、getStatusText()getHeaders()getResponseBodyAsString()。您还可以获取使用方法 getRequest.

发送的请求的参考
  1. 在构造 webclient bean 时使用 ExchangeFilterFunction
  @Bean
  public WebClient buildWebClient() {

    Function<ClientResponse, Mono<ClientResponse>> webclientResponseProcessor =
        clientResponse -> {
          HttpStatus responseStatus = clientResponse.statusCode();
          if (responseStatus.is4xxClientError()) {
            System.out.println("4xx error");
            return Mono.error(new MyCustomClientException());
          } else if (responseStatus.is5xxServerError()) {
            System.out.println("5xx error");
            return Mono.error(new MyCustomClientException());
          }
          return Mono.just(clientResponse);
        };

    return WebClient.builder()
        .filter(ExchangeFilterFunction.ofResponseProcessor(webclientResponseProcessor)).build();
  }

然后您可以使用 @ExceptionHandler 处理 MyCustomClientException 或保持原样。