Search code examples
javaspringapache-httpclient-4.xapache-httpclient-5.x

Can the same HttpClient-using code compile against Spring-5.x and 6.x?


The following code compiles nicely against Spring-5.x:

import org.apache.http.client.HttpClient;

...

    private static ClientHttpRequestFactory clientHttpRequestFactory(
        int timeOut) throws Exception
    {
        HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory =
            new HttpComponentsClientHttpRequestFactory(
            httpClient());
        httpComponentsClientHttpRequestFactory.setConnectTimeout(timeOut * 10000);
        return httpComponentsClientHttpRequestFactory;
    }

    private static HttpClient httpClient() throws Exception
    {
        SSLConnectionSocketFactory sslConnectionSocketFactory = new
            SSLConnectionSocketFactory(createSSLContext());
        return HttpClients.custom().setSSLSocketFactory(
            sslConnectionSocketFactory).build();
    }

Trying to build against Spring-6.x, however, I get an error: incompatible types: org.apache.http.client.HttpClient cannot be converted to org.apache.hc.client5.http.classic.HttpClient.

With C-code, I'd just use something like #if SPRING_VERSION > 500000 -- but this is Java... Can I import a different HttpClient -- at compile-time -- depending on the version of Spring being used?

Any other suggestions -- to keep using the same code?


Solution

  • Spring 5.x

    <dependency>
       <groupId>org.apache.httpcomponents</groupId>
       <artifactId>httpclient</artifactId>
       <version>4.5.13</version>
    </dependency>
    

    Example code

    import org.apache.http.client.HttpClient;
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    import org.apache.http.impl.client.HttpClients;
    import org.springframework.http.client.ClientHttpRequestFactory;
    import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
    import javax.net.ssl.SSLContext;
    
    ...
    //YOUR CODE
     private static HttpClient httpClient() throws Exception
        {
            SSLConnectionSocketFactory sslConnectionSocketFactory = new
                SSLConnectionSocketFactory(createSSLContext());
            return HttpClients.custom().setSSLSocketFactory(
                sslConnectionSocketFactory).build();
        }
    

    Spring 6.x

    <dependency>
      <groupId>org.apache.httpcomponents.client5</groupId>
      <artifactId>httpclient5</artifactId>
      <version>5.2.3</version>
    </dependency>
    

    Example code

    import org.apache.hc.client5.http.classic.HttpClient;
    import org.apache.hc.client5.http.impl.classic.HttpClients;
    import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
    import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
    import org.springframework.http.client.ClientHttpRequestFactory;
    import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
    import javax.net.ssl.SSLContext;
    ...
    
        private static HttpClient httpClient() throws Exception
        {
            SSLConnectionSocketFactory sslConnectionSocketFactory = new
                SSLConnectionSocketFactory(createSSLContext());
    
            PoolingHttpClientConnectionManagerBuilder cmBuilder = PoolingHttpClientConnectionManagerBuilder.create()
                    .setSSLSocketFactory(sslConnectionSocketFactory)
                    .setMaxConnTotal(200)
                    .setMaxConnPerRoute(20);
    
            return HttpClients.custom()
                    .setConnectionManager(cmBuilder.build())
                    .build();
            /*
            return HttpClients.custom().setSSLSocketFactory(
                sslConnectionSocketFactory).build();
             */
        }
    

    HttpClient 5 does not have method setSSLSocketFactory