java - 如何在 Spring WebClient 中设置和处理超时?
问题描述
Spring docs说需要手动为WebClient配置http客户端来设置超时:https ://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#webflux-client-builder -反应器超时。但是由于 WebClient 返回响应式 Mono,因此可以(api-wise)应用.timeout
方法。
它有同样的效果吗?
此外,当一个人使用方法时,预计会使用.timeout
Reactor 。TimeoutException
如果手动完成配置,流中是否会出现相同的错误,即会doOnError(TimeoutException.class, ...)
起作用吗?
解决方案
我的发现
以特定于 http 客户端的方式设置超时将导致特定于 http 客户端的异常,即WebClient
不包装异常:
@Test
void test() {
var host = "localhost";
var endpoint = "/test";
var port = 8089;
var timeout = Duration.ofSeconds(3);
WireMockServer wireMockServer = new WireMockServer(wireMockConfig().port(8089));
wireMockServer.start();
WireMock.configureFor(host, wireMockServer.port());
WireMock.stubFor(get(urlEqualTo(endpoint))
.willReturn(aResponse().withFixedDelay((int) timeout.toMillis())));
HttpClient httpClient = HttpClient.create()
.tcpConfiguration(client ->
client.doOnConnected(conn -> conn
.addHandlerLast(new ReadTimeoutHandler((int) (timeout.toSeconds() / 2)))
.addHandlerLast(new WriteTimeoutHandler((int) (timeout.toSeconds() / 2)))));
WebClient webClient = WebClient.builder()
.baseUrl(format("http://%s:%d", host, port))
.clientConnector(new ReactorClientHttpConnector(httpClient)).build();
webClient.get().uri(endpoint).retrieve().bodyToMono(Recommendation.class).block();
}
这将导致io.netty.handler.timeout.ReadTimeoutException
.
.timeout(timeout.dividedBy(2)).block()
leads to regular TimeoutException
(java.util.concurrent
) but it's still an open question whether a web client takes care about connections afterwards (probably not).
My solution is to use http client specific configuration to ensure native and correct way to utilize connections while adding new handler that wraps http client related exception into more generic ones (or java.util.concurrent.TimeoutException
) so that WebClient
clients won't depend on provider exceptions.
推荐阅读
- php - 为什么 G-Drive 不返回我的文件列表?
- twitter-bootstrap - 遍历 Bootstrap/Reactstrap 中的数组后,结束按钮组中的空按钮
- javascript - 从嵌套在对象中的函数访问类属性
- objective-c - iPhone X 和 iOS 11 升级项目
- networking - 如何检测 youtube 流量?
- ios - 如何在 AppDelegate 之外处理 UIApplicationDidRegisterToRemoteNoticationsWithDeviceToken?
- haskell - 如何删除具有不同输出类型的两个相同 Haskell 函数中的代码重复?
- java - 难以使用 JPA/Hibernate 创建与抽象类和嵌入属性的关系
- java - Android - 立即更改 UI
- scala - Scala 中的基类是什么,就像 Java 中的 Object 一样?