在 Spring WebFlux 中,WebClient 提供了多種方式來(lái)設(shè)置響應(yīng)超時(shí)。以下是幾種常見(jiàn)的方法:
1. 使用 HttpClient
設(shè)置響應(yīng)超時(shí)
WebClient 的底層實(shí)現(xiàn)基于 Reactor Netty 的 HttpClient,可以通過(guò) HttpClient 來(lái)設(shè)置響應(yīng)超時(shí)。
java復(fù)制
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;
import java.time.Duration;
public class WebClientConfig {
public WebClient createWebClient() {
HttpClient httpClient = HttpClient.create()
.responseTimeout(Duration.ofSeconds(10)); // 設(shè)置響應(yīng)超時(shí)為 10 秒
return WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(httpClient))
.build();
}
}
2. 使用 TcpClient
設(shè)置連接超時(shí)和響應(yīng)超時(shí)
如果需要同時(shí)設(shè)置連接超時(shí)和響應(yīng)超時(shí),可以使用 TcpClient。
java復(fù)制
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;
import reactor.netty.tcp.TcpClient;
import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import java.time.Duration;
public class WebClientConfig {
public WebClient createWebClient() {
TcpClient tcpClient = TcpClient.create()
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000) // 設(shè)置連接超時(shí)為 5 秒
.doOnConnected(connection ->
connection.addHandlerLast(new ReadTimeoutHandler(10)) // 設(shè)置讀取超時(shí)為 10 秒
.addHandlerLast(new WriteTimeoutHandler(10))); // 設(shè)置寫入超時(shí)為 10 秒
HttpClient httpClient = HttpClient.from(tcpClient)
.responseTimeout(Duration.ofSeconds(10)); // 設(shè)置響應(yīng)超時(shí)為 10 秒
return WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(httpClient))
.build();
}
}
3. 使用 timeout
方法設(shè)置請(qǐng)求級(jí)超時(shí)
WebClient 的 timeout 方法可以用于設(shè)置特定請(qǐng)求的超時(shí)時(shí)間。
java復(fù)制
import org.springframework.web.reactive.function.client.WebClient;
import java.time.Duration;
public class WebClientTimeoutExample {
public static void main(String[] args) {
WebClient client = WebClient.builder()
.baseUrl("https://api.example.com")
.build();
client.get()
.uri("/data")
.retrieve()
.bodyToMono(String.class)
.timeout(Duration.ofMillis(5000)) // 設(shè)置請(qǐng)求級(jí)超時(shí)為 5 秒
.subscribe(System.out::println);
}
}
4. 使用 HttpClientRequest
設(shè)置請(qǐng)求級(jí)響應(yīng)超時(shí)
如果需要在請(qǐng)求級(jí)別設(shè)置響應(yīng)超時(shí),可以使用 HttpClientRequest。
java復(fù)制
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;
import reactor.netty.http.client.HttpClientRequest;
public class WebClientTimeoutExample {
public static void main(String[] args) {
WebClient client = WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(HttpClient.create()))
.build();
client.get()
.uri("https://api.example.com/data")
.httpRequest(httpRequest -> {
HttpClientRequest reactorRequest = httpRequest.getNativeRequest();
reactorRequest.responseTimeout(Duration.ofSeconds(2)); // 設(shè)置請(qǐng)求級(jí)響應(yīng)超時(shí)為 2 秒
})
.retrieve()
.bodyToMono(String.class)
.subscribe(System.out::println);
}
}
總結(jié)【起飛嘎嘎飛LSIXSO】
- 全局響應(yīng)超時(shí):通過(guò) HttpClient 的 responseTimeout 方法設(shè)置。
- 連接超時(shí):通過(guò) TcpClient 的 option 方法設(shè)置。
- 讀取和寫入超時(shí):通過(guò) TcpClient 的 doOnConnected 方法添加 ReadTimeoutHandler 和 WriteTimeoutHandler。
- 請(qǐng)求級(jí)超時(shí):通過(guò) timeout 方法或 HttpClientRequest 的 responseTimeout 方法設(shè)置。
- 根據(jù)具體需求選擇合適的方法來(lái)設(shè)置 WebClient 的超時(shí)時(shí)間