spring-webflux - 在 Spring WebFlux 中处理全局场景

标签 spring-webflux spring-webclient

我有一个 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 类中。您可以使用 Spring 的 ExceptionHandler 注释来处理这个问题,如下所示。
  @ExceptionHandler(WebClientResponseException.class)
  public ResponseEntity handleWebClientException(WebClientResponseException ex){
    return ResponseEntity.badRequest().body(ex.getResponseBodyAsString());
  }

注意 - 在这里您可以使用 getStatusCode()getRawStatusCode()getStatusText() 等方法根据响应状态编写复杂的条件逻辑getHeaders()getResponseBodyAsString()。您还可以获取使用 getRequest 方法发送的请求的引用。

  • 在构建 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 或保持原样。

    关于spring-webflux - 在 Spring WebFlux 中处理全局场景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62840346/

    相关文章:

    java - URL中的Webflux Webclient转义斜杠

    java - Spring 5 Reactive中的HTTP响应异常处理

    spring-webflux - 将 ClientResponse 转换为 ServerResponse

    kotlin - 如何在 Reactor Netty HTTP 客户端中设置 TCP Keepalive?

    java - Spring WebClient 在尝试转换 bodyToMono<UUID>、POST 请求时抛出不支持的媒体类型异常

    java - 如何将一系列整数从一个微服务发送到另一个微服务

    spring-cloud-loabalancer 配置静态服务器列表

    spring-webflux - 使用 R2DBC 的动机是什么?

    spring-webflux - 使用 Jetty Http Client Reactor 时,HTTPS url 会导致 NPE

    java - 如何使用 Mono & Flux 限制并发 http 请求