gpt4 book ai didi

java - 使用带有阻塞/同步请求的 Spring WebClient 使用 try/catch 捕获异常

转载 作者:行者123 更新时间:2023-12-04 04:01:40 25 4
gpt4 key购买 nike

我需要制作 同步,阻塞 请求,我正在使用 Spring 的 WebClient而不是 Spring 的 RestTemplate由于后者已被弃用。在这种情况下,我不需要响应式功能,我只想以直接的方式使用 REST API,而不包括其他依赖项。
我有以下代码,按预期工作:

MyObject object = webClient.get()
.uri( myUri )
.retrieve()
.bodyToMono( MyObject.class )
.block()
但是,当我无法连接到 API 或连接但我得到 4xx/5xx 代码时,我需要管理这些情况。
因此,直接的方法是将调用放在 try/catch 中,然后捕获 Spring 的 WebClientResponseException ,由 .bodyToMono 抛出如果它得到一个 4xx/5xx 代码:
import org.springframework.web.reactive.function.client.WebClientResponseException;

try {

MyObject object = webClient.get()
.uri( myUri )
.retrieve()
.bodyToMono( MyObject.class )
.block()

}

catch ( WebClientResponseException e ) {

// Logic to handle the exception.

}
这可以正常工作,但如果连接被拒绝(例如,如果 URL 错误或服务已关闭)则不起作用。在这种情况下,我在控制台中得到以下信息:

reactor.core.Exceptions$ErrorCallbackNotImplemented:io.netty.channel.AbstractChannel$AnnotatedConnectException:finishConnect(..) failed: Connection refused: /127.0.0.1:8090 Causedby: io.netty.channel.AbstractChannel$AnnotatedConnectException:finishConnect(..) failed: Connection refused: /127.0.0.1:8090Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: Error hasbeen observed at the following site(s):|_ checkpoint ⇢ Request to GET http://127.0.0.1:8090/test [DefaultWebClient] Stack trace: Caused by: java.net.ConnectException:finishConnect(..) failed: Connection refusedat io.netty.channel.unix.Errors.throwConnectException(Errors.java:124)~[netty-transport-native-unix-common-4.1.48.Final.jar:4.1.48.Final](...)


我不确定我需要捕获哪个异常来处理这种情况。
除了上述之外,如果连接被拒绝,我还想抛出一个自定义异常,如果我收到错误代码,我想抛出一个不同的自定义异常。在第二种情况下,我尝试使用 .onStatus方法:
try {

MyObject object = webClient.get()
.uri( myUri )
.retrieve()
.onStatus( HttpStatus::is4xxClientError, response -> {
return Mono.error( new CustomClientException( "A client error ocurred" ) );
})
.bodyToMono( MyObject.class )
.block()

}

catch ( CustomClientException e ) {

// Logic to handle the exception.

}
但是异常并没有在 catch block 内捕获,尽管堆栈跟踪确实出现在控制台上。
有没有办法使用 try/catch block 处理 4xx/5xx 代码和连接错误,希望有自定义异常?或者我应该使用不同的网络客户端和/或改变我的方法?我不熟悉响应式(Reactive)编程。
提前致谢。

最佳答案

retrieve() ,在底层 HTTP 客户端上发生的所有异常都包含在 RuntimeException 中。调用ReactiveException .这样做是为了通过 react 接口(interface)冒泡检查的异常。
提供了一种获取 Exceptions.unwrap() 中实际包装异常的方法。 .然后,您可以抛出未包装的异常,稍后可以在适当的时候捕获它。一种方法可能如下:

 void makeHttpCall(..) throws Exception {
try {
// ..
// webclient request code
// ..
} catch(Exception e) {
throw Exceptions.unwrap(e);
}
}

// somewhere else:
try {
makeHttpCall(..);
} catch (ConnectException e) {
// Do your specific error handling
}
我不太喜欢用 throws Exception 声明方法但在这一点上,它根本不知道它可能是什么。

关于java - 使用带有阻塞/同步请求的 Spring WebClient 使用 try/catch 捕获异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62961858/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com