在 Spring Boot 應用程式中,我WebClient用來呼叫遠程應用程式的 POST 請求。該方法當前如下所示:
// Class A
public void sendNotification(String notification) {
final WebClient webClient = WebClient.builder()
.defaultHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE)
.build();
webClient.post()
.uri("http://localhost:9000/api")
.body(BodyInserters.fromValue(notification))
.retrieve()
.onStatus(HttpStatus::isError, clientResponse -> Mono.error(NotificationException::new))
.toBodilessEntity()
.block();
log.info("Notification delivered successfully");
}
// Class B
public void someOtherMethod() {
sendNotification("test");
}
用例是:另一個類中的一個方法呼叫sendNotification并且應該處理任何錯誤,即任何非 2xx 狀態或者如果請求甚至無法發送。
但我在處理WebClient. 據我了解,以下行將捕獲除 2xx/3xx 之外的任何 HTTP 狀態,然后回傳 a Mono.error(NotificationException自定義例外擴展Exception)。
onStatus(HttpStatus::isError, clientResponse -> Mono.error(NotificationException::new))
但是如何someOtherMethod()處理這種錯誤情況呢?它怎么能處理這個Mono.error?或者它實際上是如何捕捉到NotificationExceptionifsendNotification甚至沒有把它扔到簽名中的?
uj5u.com熱心網友回復:
好吧,有很多方法可以處理錯誤,這實際上取決于您在發生錯誤時要做什么。
在您當前的設定中,解決方案很簡單:首先,NotificationException應該擴展RuntimeException,因此,如果出現 HTTP 錯誤,.block()將拋出NotificationException. 最好將它添加到方法的簽名中,并附帶一個 Javadoc 條目。
在另一種方法中,您只需要捕獲例外并使用它做您想做的事情。
/**
* @param notification
* @throws NotificationException in case of a HTTP error
*/
public void sendNotification(String notification) throws NotificationException {
final WebClient webClient = WebClient.builder()
.defaultHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE)
.build();
webClient.post()
.uri("http://localhost:9000/api")
.body(BodyInserters.fromValue(notification))
.retrieve()
.onStatus(HttpStatus::isError, clientResponse -> Mono.error(NotificationException::new))
.toBodilessEntity()
.block();
log.info("Notification delivered successfully");
}
public void someOtherMethod() {
try {
sendNotification("test");
} catch (NotificationException e) {
// Treat exception
}
}
在更具反應性的風格中,您可以回傳 aMono并使用onErrorResume()。
public Mono<Void> sendNotification(String notification) {
final WebClient webClient = WebClient.builder()
.defaultHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE)
.build();
return webClient.post()
.uri("http://localhost:9000/api")
.body(BodyInserters.fromValue(notification))
.retrieve()
.onStatus(HttpStatus::isError, clientResponse -> Mono.error(NotificationException::new))
.bodyToMono(Void.class);
}
public void someOtherMethod() {
sendNotification("test")
.onErrorResume(NotificationException.class, ex -> {
log.error(ex.getMessage());
return Mono.empty();
})
.doOnSuccess(unused -> log.info("Notification delivered successfully"))
.block();
}
uj5u.com熱心網友回復:
使用命令式/阻塞式你可以用 try-catch 包圍它:
try {
webClient.post()
.uri("http://localhost:9000/api")
.body(BodyInserters.fromValue(notification))
.retrieve()
.onStatus(HttpStatus::isError, clientResponse -> Mono.error(NotificationException::new))
.toBodilessEntity()
.block();
} catch(NotificationException e) {...}
一個反應式解決方案是使用這樣的onErrorResume運算子:
webClient.post()
.uri("http://localhost:9000/api")
.body(BodyInserters.fromValue(notification))
.retrieve()
.onErrorResume(e -> someOtherMethod())
.toBodilessEntity()
.block();
在這里,回應式方法someOtherMethod()將在任何錯誤的情況下執行。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/417598.html
標籤:
