在 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);
}
两种方法:
- 网络客户端的异常都包含在 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.
发送的请求的参考
- 在构造 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 或保持原样。
我有一个 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 class 中。您可以像这样使用 Spring 的 ExceptionHandler 注释来处理它。
@ExceptionHandler(WebClientResponseException.class)
public ResponseEntity handleWebClientException(WebClientResponseException ex){
return ResponseEntity.badRequest().body(ex.getResponseBodyAsString());
}
注意 - 您可以在此处根据响应状态编写复杂的条件逻辑,方法是使用 getStatusCode()、getRawStatusCode()[=33= 等方法]、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 或保持原样。