How to use HttpComponentsClientHttpRequestFactory with RestTemplate efficiently?

20,448

In one of my projects, I had created a static instance of HttpComponentsClientHttpRequestFactory and passed it to every RestTemplate. Though, in here, it is suggested to also have a global instance of RestTemplate.

Maybe irrelevant, but one important point is to pass HttpClients.createDefault() to your HttpComponentsClientHttpRequestFactory while constructing it since by default, this factory uses system properties to create HttpClient for your factory and that may cause a lot of pain in production environment. You may also pass your custom HttpClient.

Share:
20,448
AKIWEB
Author by

AKIWEB

Updated on July 09, 2022

Comments

  • AKIWEB
    AKIWEB almost 2 years

    I am using RestTemplate along with its factory HttpComponentsClientHttpRequestFactory in one of my projects. In this project, I need to make a Http url call to my server which is running a restful service which returns back the response as a JSON String.

    Below is my code -

    public class GetUserClientData {
    
        public String getData(KeyHolder keys) {
            return new HTTPRequestAccess(keys).makeHttpRequest();
        }
    }
    

    Below is my class which wraps the HttpClient part -

    public class HTTPRequestAccess {
    
        // should this be static?
        private RestTemplate restTemplate;
        private KeyHolder keys;
        private int timeout;
    
        public HTTPRequestAccess(KeyHolder keys){
            this(keys.getTimeoutValue()); // setting timeout to RestTemplate
            this.keys = keys;
        }
    
        public HTTPRequestAccess(int timeout) {
            this.timeout = timeout;
            restTemplate = new RestTemplate(clientHttpRequestFactory());
        }
    
        private ClientHttpRequestFactory clientHttpRequestFactory() {
            // is this not expensive that every time we are creating this new object?
            HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
            factory.setReadTimeout(timeout);
            factory.setConnectTimeout(timeout);
            return factory;
        }
    
        public String makeHttpRequest() {
            String response = null;        
            try {
                // some logic here
    
                String url = generateURL();
                response = restTemplate.getForObject(url, String.class);
    
                // some logic here
            } catch (RestClientException ex) {
                // log exception and do some stuff
            } catch (Exception ex) {
                // log exception
            }
    
            return response;
        }
    }
    

    Should RestTemplate and HttpComponentsClientHttpRequestFactory be static here in my HTTPRequestAccess class as if I see it correctly, I am recreating the whole connection pool for each request in RestTemplate which is not the right way I guess because each factory has connection and thread pool and they are pretty heavy object I guess.

    In general what is the best way to use RestTemplate along with its factory HttpComponentsClientHttpRequestFactory in a multithreading environment? I guess RestTemplate is thread safe but I don't think HttpComponentsClientHttpRequestFactory is thread safe. Correct me if I am wrong? I will be running this library under heavy load.

    I am using spring-web-3.2.8.RELEASE version.