To create a pooled RestTemplate we need to use HttpComponentsClientHttpRequestFactory which uses CloseableHttpClient from httpclient library (at least version 4.3 to support timeout.
1. Dependencies
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
2. Create HttpComponentsClientHttpRequestFactory
private HttpComponentsClientHttpRequestFactory newHttpComponentsClientHttpRequestFactory() {
final PoolingHttpClientConnectionManager poolingHttpClientConnectionManager =
new PoolingHttpClientConnectionManager();
poolingHttpClientConnectionManager.setDefaultMaxPerRoute(100);
poolingHttpClientConnectionManager.setMaxTotal(100);
final RequestConfig requestConfig = RequestConfig.custom()
.setConnectionRequestTimeout(100)
.setConnectTimeout(100)
.setSocketTimeout(100)
.build();
CloseableHttpClient closeableHttpClient = HttpClientBuilder.create()
.setConnectionManager(poolingHttpClientConnectionManager)
.setDefaultRequestConfig(requestConfig)
.build();
final HttpComponentsClientHttpRequestFactory httpRequestFactory =
new HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setConnectionRequestTimeout(connectionRequestTimeout);
httpRequestFactory.setConnectTimeout(100);
httpRequestFactory.setReadTimeout(100);
httpRequestFactory.setHttpClient(closeableHttpClient);
return httpRequestFactory;
}
3. Create RestTemplate
private RestTemplate newRestTemplate(final HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory) {
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new Jackson2HalModule());
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessagemappingJackson2HttpMessageConverter();
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Arrays.asList(MediaTypes.HAL_JSON, MediaType.APPLICATION_JSON));
mappingJackson2HttpMessageConverter.setObjectobjectMapper(objectMapper);
final DefaultUriBuilderFactory defaultUriBuilderFactory = new DefaultUriBuilderFactory();
defaultUriBuilderFactory.setEncodingMode(DefaultUriBuilderFactory.EncodingMode.VALUES_ONLY);
return new RestTemplateBuilder()
.messagemappingJackson2HttpMessageConverters(mappingJackson2HttpMessageConverter)
.rootUri(baseUrl)
.uriTemplateHandler(defaultUriBuilderFactory)
.requestFactory(() -> httpComponentsClientHttpRequestFactory)
.build();
}
4. How to Use
final RestTemplate restTemplate = newRestTemplate(newHttpComponentsClientHttpRequestFactory());
5. Improvements
Create a Configuration class for the number values.
Originally published at https://www.czetsuyatech.com/2022/03/spring-rest-how-to-create-a-pooled-resttemplate.html.