我有一个 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);
}
最佳答案
两种方法:
- 网络客户端的异常都封装在 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/