You are viewing a plain text version of this content. The canonical link for it is here.
Posted to httpclient-users@hc.apache.org by Check Peck <co...@gmail.com> on 2015/06/07 18:15:03 UTC

How to use RestTemplate with PoolingHttpClientConnectionManager

I am using Spring RestTemplate as my HttpClient in my project and I want to
use connection pooling feature with RestTemplate. After reading more on
HttpClient and RestTemplate, I was able to come up with this example which
uses PoolingHttpClientConnectionManager class with RestTemplate but I am
pretty sure the way I am using is not right. Can anyone help me to
understand what is the right way to use these two in my below code.

I have put everything in gist here -

https://gist.github.com/TechGeeky/3f32a621bc9d8043197b

Also below is the code as well which shows how I am using.

    public class DataClient implements Client {

        // here I am setting request factory to my RestTemplate
        private RestTemplate restTemplate = new
RestTemplate(RestTemplateConnectionPooling.getInstance()
            .getRequestFactory());
        private ExecutorService executor = Executors.newFixedThreadPool(10);

        // for synchronous call
        @Override
        public DataResponse executeSynchronous(DataKey key) {
            DataResponse dataResponse = null;
            Future<DataResponse> future = null;

            try {
                future = executeAsynchronous(key);
                dataResponse = future.get(key.getTimeout(),
TimeUnit.MILLISECONDS);
            } catch (TimeoutException ex) {
                // log exception
                dataResponse = new DataResponse(null,
DataErrorEnum.TIMEOUT_ON_CLIENT, DataStatusEnum.ERROR);
                future.cancel(true); // terminating tasks that have timed
out
            } catch (Exception ex) {
                // log exception
                dataResponse = new DataResponse(null,
DataErrorEnum.CLIENT_ERROR, DataStatusEnum.ERROR);
            }

            return dataResponse;
        }

        //for asynchronous call
        @Override
        public Future<DataResponse> executeAsynchronous(DataKey key) {
            Future<DataResponse> future = null;

            try {
                Task task = new Task(key, restTemplate);
                future = executor.submit(task);
            } catch (Exception ex) {
                // log exception
            }

            return future;
        }
    }

A simple class which will perform the actual task:

    public class Task implements Callable<DataResponse> {

        private final DataKey key;
        private final RestTemplate restTemplate;

        public Task(DataKey key, RestTemplate restTemplate) {
            this.key = key;
            this.restTemplate = restTemplate;
        }

        @Override
        public DataResponse call() {

            // use RestTemplate here to make Http call and get the data
            // and then return the "DataResponse" back

        }
    }

Below is where I am having PoolingHttpClientConnectionManager
initialization as part of singleton class. Do I need this class at all if I
want to use RestTemplate with PoolingHttpClientConnectionManager?

    public class RestTemplateConnectionPooling {

        private final HttpComponentsClientHttpRequestFactory requestFactory
= new HttpComponentsClientHttpRequestFactory();

        private static class Holder {
            private static final RestTemplateConnectionPooling INSTANCE =
new RestTemplateConnectionPooling();
        }

        public static RestTemplateConnectionPooling getInstance() {
            return Holder.INSTANCE;
        }

        private RestTemplateConnectionPooling() {
            RequestConfig requestConfig =
RequestConfig.custom().setConnectTimeout(1000).setSocketTimeout(1000)
                    .setStaleConnectionCheckEnabled(false).build();
            PoolingHttpClientConnectionManager
poolingHttpClientConnectionManager = new
PoolingHttpClientConnectionManager();
            poolingHttpClientConnectionManager.setMaxTotal(200);
            poolingHttpClientConnectionManager.setDefaultMaxPerRoute(20);

            CloseableHttpClient httpClientBuilder =
HttpClientBuilder.create()

.setConnectionManager(poolingHttpClientConnectionManager).setDefaultRequestConfig(requestConfig)
                    .build();

            requestFactory.setHttpClient(httpClientBuilder);
        }

        public HttpComponentsClientHttpRequestFactory getRequestFactory() {
            return requestFactory;
        }
    }

Now my question is - Does this look right the way I am using RestTemplate
with PoolingHttpClientConnectionManager? Is there any better way to use
connection pooling with RestTemplate?

I am using http-client 4.3.1 and spring-web 3.2.8.

Re: How to use RestTemplate with PoolingHttpClientConnectionManager

Posted by Oleg Kalnichevski <ol...@apache.org>.
On Sun, 2015-06-07 at 09:15 -0700, Check Peck wrote:
> I am using Spring RestTemplate as my HttpClient in my project and I want to
> use connection pooling feature with RestTemplate. After reading more on
> HttpClient and RestTemplate, I was able to come up with this example which
> uses PoolingHttpClientConnectionManager class with RestTemplate but I am
> pretty sure the way I am using is not right. Can anyone help me to
> understand what is the right way to use these two in my below code.
> 
> I have put everything in gist here -
> 
> https://gist.github.com/TechGeeky/3f32a621bc9d8043197b
> 
> Also below is the code as well which shows how I am using.
> 
>     public class DataClient implements Client {
> 
>         // here I am setting request factory to my RestTemplate
>         private RestTemplate restTemplate = new
> RestTemplate(RestTemplateConnectionPooling.getInstance()
>             .getRequestFactory());
>         private ExecutorService executor = Executors.newFixedThreadPool(10);
> 
>         // for synchronous call
>         @Override
>         public DataResponse executeSynchronous(DataKey key) {
>             DataResponse dataResponse = null;
>             Future<DataResponse> future = null;
> 
>             try {
>                 future = executeAsynchronous(key);
>                 dataResponse = future.get(key.getTimeout(),
> TimeUnit.MILLISECONDS);
>             } catch (TimeoutException ex) {
>                 // log exception
>                 dataResponse = new DataResponse(null,
> DataErrorEnum.TIMEOUT_ON_CLIENT, DataStatusEnum.ERROR);
>                 future.cancel(true); // terminating tasks that have timed
> out
>             } catch (Exception ex) {
>                 // log exception
>                 dataResponse = new DataResponse(null,
> DataErrorEnum.CLIENT_ERROR, DataStatusEnum.ERROR);
>             }
> 
>             return dataResponse;
>         }
> 
>         //for asynchronous call
>         @Override
>         public Future<DataResponse> executeAsynchronous(DataKey key) {
>             Future<DataResponse> future = null;
> 
>             try {
>                 Task task = new Task(key, restTemplate);
>                 future = executor.submit(task);
>             } catch (Exception ex) {
>                 // log exception
>             }
> 
>             return future;
>         }
>     }
> 
> A simple class which will perform the actual task:
> 
>     public class Task implements Callable<DataResponse> {
> 
>         private final DataKey key;
>         private final RestTemplate restTemplate;
> 
>         public Task(DataKey key, RestTemplate restTemplate) {
>             this.key = key;
>             this.restTemplate = restTemplate;
>         }
> 
>         @Override
>         public DataResponse call() {
> 
>             // use RestTemplate here to make Http call and get the data
>             // and then return the "DataResponse" back
> 
>         }
>     }
> 
> Below is where I am having PoolingHttpClientConnectionManager
> initialization as part of singleton class. Do I need this class at all if I
> want to use RestTemplate with PoolingHttpClientConnectionManager?
> 
>     public class RestTemplateConnectionPooling {
> 
>         private final HttpComponentsClientHttpRequestFactory requestFactory
> = new HttpComponentsClientHttpRequestFactory();
> 
>         private static class Holder {
>             private static final RestTemplateConnectionPooling INSTANCE =
> new RestTemplateConnectionPooling();
>         }
> 
>         public static RestTemplateConnectionPooling getInstance() {
>             return Holder.INSTANCE;
>         }
> 
>         private RestTemplateConnectionPooling() {
>             RequestConfig requestConfig =
> RequestConfig.custom().setConnectTimeout(1000).setSocketTimeout(1000)
>                     .setStaleConnectionCheckEnabled(false).build();
>             PoolingHttpClientConnectionManager
> poolingHttpClientConnectionManager = new
> PoolingHttpClientConnectionManager();
>             poolingHttpClientConnectionManager.setMaxTotal(200);
>             poolingHttpClientConnectionManager.setDefaultMaxPerRoute(20);
> 
>             CloseableHttpClient httpClientBuilder =
> HttpClientBuilder.create()
> 
> .setConnectionManager(poolingHttpClientConnectionManager).setDefaultRequestConfig(requestConfig)
>                     .build();
> 
>             requestFactory.setHttpClient(httpClientBuilder);
>         }
> 
>         public HttpComponentsClientHttpRequestFactory getRequestFactory() {
>             return requestFactory;
>         }
>     }
> 
> Now my question is - Does this look right the way I am using RestTemplate
> with PoolingHttpClientConnectionManager? Is there any better way to use
> connection pooling with RestTemplate?
> 
> I am using http-client 4.3.1 and spring-web 3.2.8.

You should probably direct this question to the Spring support forum.

Oleg



---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscribe@hc.apache.org
For additional commands, e-mail: httpclient-users-help@hc.apache.org