Reputation: 185
Currently my post and get requests are handled through WebClients which has a common connection and read timeout in Spring Boot. I have 5 different classes each requiring its own set of connection and read timeout. I don't want to create 5 different WebClients, rather use the same Webclient but while sending a post or a get request from a particular class, specify the required connection and read timeout. Is there any way to implement this?
My current WebClient:
@Bean
public WebClient getWebClient(WebClient.Builder builder){
HttpClient httpClient = HttpClient.newConnection()
.tcpConfiguration(tcpClient -> {
tcpClient = tcpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectionTimeout*1000);
tcpClient = tcpClient.doOnConnected(conn -> conn
.addHandlerLast(new ReadTimeoutHandler(readTimeout, TimeUnit.SECONDS)));
return tcpClient;
}).wiretap(true);
ClientHttpConnector connector = new ReactorClientHttpConnector(httpClient);
return builder.clientConnector(connector).build();
}
A post request I'm using:
public WebClientResponse httpPost(String endpoint, String requestData, Map<String, Object> requestHeader) {
ClientResponse res = webClient.post().uri(endpoint)
.body(BodyInserters.fromObject(requestData))
.headers(x -> {
if(requestHeader != null && !requestHeader.isEmpty()) {
for (String s : requestHeader.keySet()) {
x.set(s, String.valueOf(requestHeader.get(s)));
}
}
})
.exchange()
.doOnSuccess(x -> log.info("response code = " + x.statusCode()))
.block();
return convertWebClientResponse(res);
}
Upvotes: 6
Views: 25166
Reputation: 51
@Bean
public WebClient getWebClient() {
HttpClient httpClient = HttpClient.create()
.tcpConfiguration(client ->
client.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 4000)
.doOnConnected(conn -> conn
.addHandlerLast(new ReadTimeoutHandler(4))
.addHandlerLast(new WriteTimeoutHandler(4))));
ClientHttpConnector connector = new ReactorClientHttpConnector(httpClient.wiretap(true));
return WebClient.builder()
.clientConnector(connector)
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) // if you need a default header
.build();
}
or you can use what @Amol has suggested
Upvotes: 0
Reputation: 369
You can try timeout
with webClient
like below,
webClient.post()
.uri(..)
.body(..)
.retrieve()
.
.
.
.timeout(Duration.ofMillis(30);
30
is just example.
Upvotes: 0
Reputation: 634
You can configure request-level timeout in WebClient.
webClient.get()
.uri("https://baeldung.com/path")
.httpRequest(httpRequest -> {
HttpClientRequest reactorRequest = httpRequest.getNativeRequest();
reactorRequest.responseTimeout(Duration.ofSeconds(2));
});
Now what you can do is that based on the request you can add those values either from the properties file or you can hard code them.
Reference:- https://www.baeldung.com/spring-webflux-timeout
Upvotes: 7