Spring RestTemplate - Need to release connection?

34,617

Solution 1

You should declare the ClientHttpRequestFactory as a bean. By declaring it as a bean, it becomes managed by the Spring bean factory, which will call the factory's destroy method when the application is closed, or the bean goes out of scope. The destroy method of the ClientHttpRequestFactory will close the underlying ClientConnectionManager's connection pool. You can check the Spring API docs for this.

@Bean
public ClientHttpRequestFactory createRequestFactory(@Value("${connection.timeout}") String maxConn) {
    PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
     connectionManager.setMaxTotal(maxTotalConn);
     connectionManager.setDefaultMaxPerRoute(maxPerChannel);

    RequestConfig config = RequestConfig.custom().setConnectTimeout(100000).build();
    CloseableHttpClient httpClient = HttpClientBuilder.create().setConnectionManager(connectionManager)
            .setDefaultRequestConfig(config).build();
    return new HttpComponentsClientHttpRequestFactory(httpClient);
}

Then you can use this bean to create your RestTemplate:

@Bean
@Qualifier("myRestService")
public RestTemplate createRestTemplate(ClientHttpRequestFactory factory) {
    RestTemplate restTemplate = new RestTemplate(factory);

    restTemplate.setErrorHandler(new RestResponseErrorHandler());
    restTemplate.setMessageConverters(createMessageConverters());

    return restTemplate;
}

Solution 2

The question which you have asked: Do i need to release the connection after the above call or is it taken care by RestTemplate. If we need to take care of releasing connection.

No, you do not need to close the connection on the response, if you use resttemplate.

From the apache httpclient, you need to consume the complete response (EntityUtils.consume(HttpEntity) and close the response.

This can be verified in the ClientConnectionRelease.java

But RestTemplate does this for you, to verify the same have a look into RestTemplate.java

Look for method

protected <T> T doExecute(URI url,...) {
 try {
        ClientHttpRequest request = this.createRequest(url, method);
        ...
        response = request.execute();
        ...
        if(responseExtractor != null) {
            var7 = responseExtractor.extractData(response);
            return var7;
        }
       ...
       ...
    } finally {
        if(response != null) {
            response.close();
        }

    }
}

Where response extractor does the work for you by consuming the response using responseExtractor.extractData(response);

And after extracting the data completely it is closing response.close() as well.

Share:
34,617
Umar
Author by

Umar

Updated on September 30, 2020

Comments

  • Umar
    Umar over 3 years

    This is my Configuration for Rest Template,

        @Bean
        @Qualifier("myRestService")
        public RestTemplate createRestTemplate(@Value("${connection.timeout}") String maxConn) {
            PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
             connectionManager.setMaxTotal(maxTotalConn);
             connectionManager.setDefaultMaxPerRoute(maxPerChannel);
    
            RequestConfig config = RequestConfig.custom().setConnectTimeout(100000).build();
            CloseableHttpClient httpClient = HttpClientBuilder.create().setConnectionManager(connectionManager)
                    .setDefaultRequestConfig(config).build();
            ClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);
    
            RestTemplate restTemplate = new RestTemplate(factory);
    
            restTemplate.setErrorHandler(new RestResponseErrorHandler());
             restTemplate.setMessageConverters(createMessageConverters());
    
            return restTemplate;
        }
    

    Am using PoolingHttpClientConnectionManager for managing the connections.

    Its being accessed by the following code,

    ResponseEntity<String> response = restClient.exchange( url, HttpMethod.GET, entity , String.class );
    

    Do i need to release the connection after the above call or is it taken care by RestTemplate. If we need to take care of releasing connection.

    Please can some one explain/show how to release the connection.

  • Umar
    Umar over 7 years
    Please can you explain more clearly probably with code samples.
  • Kalpesh Soni
    Kalpesh Soni over 6 years
    his whole point is to not close connections for each call and use apache PoolingHttpClientConnectionManager to keep socket open?
  • cwa
    cwa over 4 years
    Deepak is correct. He needs to close the connection to release it back to the connection pool.
  • hipokito
    hipokito about 4 years
    We were using ClientHttpRequestInterceptor that intercepted the RestTemplate and response was not getting closed in case of some exception.
  • Alaf Azam
    Alaf Azam almost 4 years
    Hi, What happens when response is null?
  • Hasan Can Saral
    Hasan Can Saral over 3 years
    @AlafAzam Apparently, a problem... stackoverflow.com/questions/63451808/…