Custom RestTemplate using requestFactory of RestTemplateBuilder in SpringBoot 2.1.x is not backward compatible with version 1.5.x

Tags: , ,



In Spring Boot 1.5.x, I was creating a custom RestTemplate like below:

@Bean
  public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
    PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager();
    poolingConnectionManager.setMaxTotal(restTemplateProps.getMaxConnectionsPerPool());
    poolingConnectionManager.setDefaultMaxPerRoute(restTemplateProps.getMaxDefaultConnectionPerRoute());
    CloseableHttpClient client = HttpClientBuilder.create().setConnectionManager(poolingConnectionManager).build();
    HttpComponentsClientHttpRequestFactory clientHttpRequestFactory =
        new HttpComponentsClientHttpRequestFactory(client);
    clientHttpRequestFactory.setConnectTimeout(restTemplateProps.getConnectionTimeout());
    clientHttpRequestFactory.setReadTimeout(restTemplateProps.getSocketTimeout());
    return restTemplateBuilder.requestFactory(clientHttpRequestFactory).build();
  }

But, after migrating to Spring Boot 2.1.x, the above code doesn’t compile. Looks like requestFactory doesn’t take HttpComponentsClientHttpRequestFactory as an input parameter.

Can anyone suggest how can I make the above code work in Spring Boot 2.1.x?

Answer

After digging deeper into the source code of RestTemplateBuilder of Spring Boot 2.1.x, I found that they have removed the method requestFactory(ClientHttpRequestFactory requestFactory). That means you can no longer inject the ClientHttpRequestFactory object into requestFactory method.

But, it accept a Supplier<ClientHttpRequestFactory> as the input now. So if you have only one restTemplate and one requestFactory, all you need to do is register a HttpComponentsClientHttpRequestFactory bean in Spring context and pass a ClientHttpRequestFactorySupplier to requestFactory method. The supplier will automatically detect your HttpComponentsClientHttpRequestFactory and return you the required RestTemplate.

Refer the below code for that:

@Bean
  public HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory() {
    PoolingHttpClientConnectionManager poolingConnectionManager = new PoolingHttpClientConnectionManager();
    poolingConnectionManager.setMaxTotal(restTemplateProps.getMaxConnectionsPerPool());
    poolingConnectionManager.setDefaultMaxPerRoute(restTemplateProps.getMaxDefaultConnectionPerRoute());
    CloseableHttpClient client = HttpClientBuilder.create().setConnectionManager(poolingConnectionManager).build();
    HttpComponentsClientHttpRequestFactory clientHttpRequestFactory =
        new HttpComponentsClientHttpRequestFactory(client);
    clientHttpRequestFactory.setConnectTimeout(restTemplateProps.getConnectionTimeout());
    clientHttpRequestFactory.setReadTimeout(restTemplateProps.getSocketTimeout());
    return clientHttpRequestFactory;
  }

  @Bean
  public RestTemplate authRestTemplate(RestTemplateBuilder restTemplateBuilder) {
    return restTemplateBuilder.requestFactory(new ClientHttpRequestFactorySupplier()).build();
  }

For those who are interested in all the changes made to RestTemplateBuilder in SpringBoot 2.1.x, please refer this.



Source: stackoverflow