Search code examples
springspring-bootapache-httpclient-4.xapache-httpclient-5.x

required a bean of type 'org.apache.hc.client5.http.io.HttpClientConnectionManager' that could not be found


I want to migrate this apache http client code:

import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.TrustStrategy;

  @Bean
  public RestTemplate restTemplate(HttpClientConnectionManager httpClientConnectionManager)
      throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
    TrustStrategy trustStrategy = (X509Certificate[] chain, String authType) -> true;
    SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom().loadTrustMaterial(null, trustStrategy).build();
    SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
    CloseableHttpClient httpClient = HttpClients.custom()
                                                .setConnectionManager(httpClientConnectionManager)
                                                .setSSLSocketFactory(csf)
                                                .build();
    HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
    requestFactory.setConnectTimeout(20);
    requestFactory.setReadTimeout(20);
    requestFactory.setHttpClient(httpClient);
    return new RestTemplate(new BufferingClientHttpRequestFactory(requestFactory));
  }

I tried to migrate this code to apache http 5 code:

import org.apache.hc.client5.http.config.ConnectionConfig;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.io.HttpClientConnectionManager;
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
import org.apache.hc.core5.http.io.SocketConfig;
import org.apache.hc.core5.ssl.TrustStrategy;
import org.apache.hc.core5.util.Timeout;

  @Bean
  public RestTemplate restTemplate(HttpClientConnectionManager httpClientConnectionManager)
      throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {

    ConnectionConfig connectionConfig = ConnectionConfig.custom()
            .setConnectTimeout(Timeout.ofMilliseconds(20))
            .build();
    SocketConfig socketConfig = SocketConfig.custom()
            .setSoTimeout(Timeout.ofMilliseconds(20))
            .build();
    RequestConfig requestConfig = RequestConfig.custom()
            .setConnectionRequestTimeout(Timeout.ofMilliseconds(20)) 
            .build();

    TrustStrategy trustStrategy = (X509Certificate[] chain, String authType) -> true;
    SSLContext sslContext = org.apache.hc.core5.ssl.SSLContexts.custom().loadTrustMaterial(null, trustStrategy).build();

    SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
    PoolingHttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create()
            .setDefaultSocketConfig(socketConfig)
            .setDefaultConnectionConfig(connectionConfig)
            .setSSLSocketFactory(csf).build();

    CloseableHttpClient httpClient = HttpClients.custom()
            .setConnectionManager(connectionManager)
            .setDefaultRequestConfig(requestConfig)
            .build();
    HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
    requestFactory.setConnectTimeout(connectTimeout);
    requestFactory.setHttpClient(httpClient);
    return new RestTemplate(new BufferingClientHttpRequestFactory(requestFactory));
  }

During startup I get error:

required a bean of type 'org.apache.hc.client5.http.io.HttpClientConnectionManager' that could not be found.

What is the proper way to replace HttpClientConnectionManager httpClientConnectionManager? Should I replace it or just remove it?

I use implementation 'org.apache.httpcomponents.client5:httpclient5:5.3.1'

Full code example: https://github.com/rcbandit111/apache_http5_client_migration_poc/blob/main/src/main/java/com/test/client/ClientConfiguration.java


Solution

  • Thanks for sharing your example repo. You need to change the signature of your restTemplate method.

    @Bean
      public RestTemplate restTemplate(HttpClientConnectionManager httpClientConnectionManager)
          throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
    

    You do not need to pass in HttpClientConnectionManager, you are creating the PoolingHttpClientConnectionManager within your configuration method.

    Change the method signature to

    @Bean
      public RestTemplate restTemplate()
          throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
    

    I was able to start up the project without any problems.