【问题标题】:How to handle exceptions thrown by the webclient?如何处理 webclient 抛出的异常?
【发布时间】:2019-03-20 04:16:49
【问题描述】:

我试图弄清楚如何从 web 客户端记录异常,无论从被调用的 api 返回的错误状态代码如何。

我见过以下实现:

.onStatus(status -> status.value() != HttpStatus.OK.value(),
            rs -> rs.bodyToMono(String.class).map(body -> new IOException(String.format(
                "Response HTTP code is different from 200: %s, body: '%s'", rs.statusCode(), body))))

我见过的另一个例子是使用过滤器。我猜这个过滤器也可以用来记录错误,除了这个例子中的请求:

public MyClient(WebClient.Builder webClientBuilder) {
    webClient = webClientBuilder // you can also just use WebClient.builder()
            .baseUrl("https://httpbin.org")
            .filter(logRequest()) // here is the magic
            .build();
}

但是我们是否认真对待这件事没有专门的异常处理程序?

【问题讨论】:

    标签: spring-boot spring-webflux


    【解决方案1】:

    找到了。
    bodyToMono 如果状态码为 4xx(客户端错误)或 5xx(服务器错误),则抛出 WebClientException。

    服务的完整实现:​​

    @Service
    public class FacebookService {
        private static final Logger LOG = LoggerFactory.getLogger(FacebookService.class);
        private static final String URL_DEBUG = "https://graph.facebook.com/debug_token";
        private WebClient webClient;
    
        public FacebookService() {
            webClient = WebClient.builder()
                    .filter(logRequest())
                    .build();
        }
    
        public Mono<DebugTokenResponse> verifyFbAccessToken(String fbAccessToken, String fbAppToken) {
            LOG.info("verifyFacebookToken for " + String.format("fbAccessToken: %s and fbAppToken: %s", fbAccessToken, fbAppToken));
            UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(URL_DEBUG)
                    .queryParam("input_token", fbAccessToken)
                    .queryParam("access_token", fbAppToken);
            return this.webClient.get()
                    .uri(builder.toUriString())
                    .retrieve()
                    .bodyToMono(DebugTokenResponse.class);
        }
    
        private static ExchangeFilterFunction logRequest() {
            return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
                LOG.info("Request: {} {}", clientRequest.method(), clientRequest.url());
                clientRequest.headers().forEach((name, values) -> values.forEach(value -> LOG.info("{}={}", name, value)));
                return Mono.just(clientRequest);
            });
        }
    
        @ExceptionHandler(WebClientResponseException.class)
        public ResponseEntity<String> handleWebClientResponseException(WebClientResponseException ex) {
            LOG.error("Error from WebClient - Status {}, Body {}", ex.getRawStatusCode(), ex.getResponseBodyAsString(), ex);
            return ResponseEntity.status(ex.getRawStatusCode()).body(ex.getResponseBodyAsString());
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-02-13
      • 2021-03-12
      • 1970-01-01
      • 1970-01-01
      • 2013-07-24
      • 2022-11-25
      • 2021-12-22
      • 2013-03-05
      • 1970-01-01
      相关资源
      最近更新 更多