亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用Springboot對WebFlux進行異常處理?

如何使用Springboot對WebFlux進行異常處理?

慕尼黑5688855 2023-08-09 17:16:56
我有 3 個微服務應用程序。我正在嘗試使用反應包中的 webclient 進行 2 次異步調用,然后在收到響應時將它們組合起來。示例代碼:(引用自 - https://docs.spring.io/spring/docs/5.1.9.RELEASE/spring-framework-reference/web-reactive.html#webflux-client-synchronous)Mono<Person> personMono = client.get().uri("/person/{id}", personId)        .retrieve().bodyToMono(Person.class);Mono<List<Hobby>> hobbiesMono = client.get().uri("/person/{id}/hobbies", personId)        .retrieve().bodyToFlux(Hobby.class).collectList();Map<String, Object> data = Mono.zip(personMono, hobbiesMono, (person, hobbies) -> {            Map<String, String> map = new LinkedHashMap<>();            map.put("person", personName);            map.put("hobbies", hobbies);            return map;        })        .block();我的問題是如何向 get 調用添加異常處理?如何檢查我是否收到 404 或 204 或其他信息?我努力了:將 .onStatus() 添加到 GET 調用    .onStatus(HttpStatus::is4xxClientError, clientResponse ->             Mono.error(new Data4xxException(String.format(                "Could not GET data with id: %s from another app, due to error:                  %s", key, clientResponse))))    .onStatus(HttpStatus::is5xxServerError, clientResponse ->          Mono.error(new Data5xxException(              String.format("For Data %s, Error Occurred: %s", key, clientResponse))))添加異常處理程序 - 但我確實沒有控制器,所以這似乎不起作用。@ExceptionHandler(WebClientException.class)    public Exception handlerWebClientException(WebClientException webClientException) {        return new Data4xxException("Testing", webClientException);    }添加了一個包含 ControllerAdvice 和 ExceptionHandler 的類@ControllerAdvicepublic class WebFluxExceptionHandler {    @ExceptionHandler(WebClientException.class)    public Exception handlerWebClientException(WebClientException webClientException) {        return new Data4xxException("Testing", webClientException);    }}但我沒有看到它們打印在 spring-boot 日志中。Mono.zip.block() 方法只是返回 null 并且實際上不會拋出任何異常。如何讓 zip 方法拋出異常而不返回 null ?
查看完整描述

3 回答

?
一只萌萌小番薯

TA貢獻1795條經驗 獲得超7個贊

執行此操作的方法是按以下方式使用 onErrorMap:


Mono<Person> personMono = client.get()

.uri("/person/{id}", personId)

.retrieve()

.bodyToMono(Person.class)

.onErrorMap((Throwable error) -> error);

onErrorMap將使 Mono 在 Zip 阻塞時真正拋出錯誤,終止 zip 并讓 spring 或任何其他您想要處理異常的類。


查看完整回答
反對 回復 2023-08-09
?
HUWWW

TA貢獻1874條經驗 獲得超12個贊

你問的時候不是很清楚


“如何讓 zip 方法拋出異常而不返回 null?”


在 WebFlux 中,您通常不會拋出異常,而是傳播異常然后處理它們。為什么?因為我們正在處理數據流,如果拋出異常,流就會結束,客戶端會斷開連接,事件鏈也會停止。


我們仍然希望維護數據流并在數據流經時處理不良數據。


您可以使用該doOnError方法處理錯誤。


.onStatus(HttpStatus::is4xxClientError, clientResponse ->

         Mono.error(new Data4xxException(String.format(

            "Could not GET data with id: %s from another app, due to error: 

             %s", key, clientResponse))))


Mono.zip( .. ).doOnError( //Handle your error, log or whatever )

如果您想做更具體的事情,您必須用您希望如何處理錯誤來更新您的問題。


查看完整回答
反對 回復 2023-08-09
?
HUH函數

TA貢獻1836條經驗 獲得超4個贊

每當收到狀態碼為 4xx 或 5xx 的響應時,WebClient 中的retrieve() 方法就會拋出 WebClientResponseException。


與retrieve()方法不同,exchange()方法在4xx或5xx響應的情況下不會拋出異常。您需要自己檢查狀態代碼并按照您想要的方式處理它們。


? ?Mono<Object> result = webClient.get().uri(URL).exchange().log().flatMap(entity -> {

? ? ? ? HttpStatus statusCode = entity.statusCode();

? ? ? ? if (statusCode.is4xxClientError() || statusCode.is5xxServerError())

? ? ? ? {

? ? ? ? ? ? return Mono.error(new Exception(statusCode.toString()));

? ? ? ? }

? ? ? ? return Mono.just(entity);

? ? }).flatMap(clientResponse -> clientResponse.bodyToMono(JSONObject.class))

查看完整回答
反對 回復 2023-08-09
  • 3 回答
  • 0 關注
  • 351 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號