afs*_*s35 10 java rest spring spring-boot spring-webclient
我需要发出同步的阻塞请求,并且我正在使用 SpringWebClient而不是 Spring RestTemplate,因为后者已被弃用。在这种情况下,我不需要反应式功能,我只想以简单的方式使用 REST API,而不包含额外的依赖项。
我有以下代码,其按预期工作:
\nMyObject object = webClient.get()\n .uri( myUri )\n .retrieve()\n .bodyToMono( MyObject.class )\n .block()\nRun Code Online (Sandbox Code Playgroud)\n但是,我需要处理无法连接到 API 或连接但收到 4xx/5xx 代码时的情况。
\n因此,最简单的方法是将调用放入 try/catch 中,并捕获 Spring 的,如果它获得 4xx/5xx 代码,WebClientResponseException则会抛出该错误:.bodyToMono
import org.springframework.web.reactive.function.client.WebClientResponseException;\n\ntry {\n\n MyObject object = webClient.get()\n .uri( myUri )\n .retrieve()\n .bodyToMono( MyObject.class )\n .block()\n\n}\n\ncatch ( WebClientResponseException e ) {\n\n // Logic to handle the exception.\n\n}\nRun Code Online (Sandbox Code Playgroud)\n这工作正常,但如果连接被拒绝(例如,如果 URL 错误或服务关闭),则不起作用。在这种情况下,我在控制台中看到以下内容:
\n\n\nreactor.core.Exceptions$ErrorCallbackNotImplemented:\nio.netty.channel.AbstractChannel$AnnotatedConnectException:\nfinishConnect(..) 失败: 连接被拒绝: /127.0.0.1:8090 引起\n由: io.netty.channel.AbstractChannel$AnnotatedConnectException: \nfinishConnect(..) 失败:连接被拒绝:/127.0.0.1:8090\n抑制:reactor.core.publisher.FluxOnAssembly$OnAssemblyException:在以下站点\n观察到错误:\n|_ 检查点 \xe2 \x87\xa2 请求 GET http://127.0.0.1:8090/test [DefaultWebClient] 堆栈跟踪:引起原因:java.net.ConnectException:\nfinishConnect(..) 失败:连接被拒绝\nat io.netty.channel .unix.Errors.throwConnectException(Errors.java:124)\n~[netty-transport-native-unix-common-4.1.48.Final.jar:4.1.48.Final]\n(...)
\n
我不确定需要捕获哪个异常来处理这种情况。
\n除了上述内容之外,如果连接被拒绝,我还想抛出一个自定义异常,如果收到错误代码,我还想抛出一个不同的自定义异常。对于第二种情况,我尝试使用以下.onStatus方法:
try {\n\n MyObject object = webClient.get()\n .uri( myUri )\n .retrieve()\n .onStatus( HttpStatus::is4xxClientError, response -> { \n return Mono.error( new CustomClientException( "A client error ocurred" ) );\n })\n .bodyToMono( MyObject.class )\n .block()\n\n}\n\ncatch ( CustomClientException e ) {\n\n // Logic to handle the exception.\n\n}\nRun Code Online (Sandbox Code Playgroud)\n但是,尽管堆栈跟踪确实出现在控制台上,但异常并未在 catch 块内捕获。
\n有没有办法使用 try/catch 块处理 4xx/5xx 代码和连接错误,希望有自定义异常?或者我应该使用不同的网络客户端和/或改变我的方法?我不熟悉反应式编程。
\n提前致谢。
\n使用retrieve(),底层 HTTP 客户端上发生的所有异常都被包装在被RuntimeException调用的ReactiveException. 这是通过反应式接口冒泡检查异常的一种方式。
提供了一种方法来获取 中实际包装的异常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
}
Run Code Online (Sandbox Code Playgroud)
我不太喜欢声明一个方法,throws Exception但目前还不知道它可能是什么。
| 归档时间: |
|
| 查看次数: |
13236 次 |
| 最近记录: |