HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Using RestTemplate with HttpComponentsClientHttpRequestFactory in a multithreaded environment

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
withenvironmentusinghttpcomponentsclienthttprequestfactoryresttemplatemultithreaded

Problem

I am working on a project in which I need to make an HTTP URL call to my server, running RESTful service, which returns the response as a JSON String. I am using RestTemplate here along with HttpComponentsClientHttpRequestFactory to execute a URL.

I have set up an HTTP request timeout (READ and CONNECTION time out) on my RestTemplate by using HttpComponentsClientHttpRequestFactory.

Here is my main code which is using the future and callables:

public class TimeoutThreadExample {

    private ExecutorService executor = Executors.newFixedThreadPool(10);
    // does it have to be static final?
    private static final RestTemplate restTemplate = createRestTemplate();

    // does this look right with the way I am creating `RestTemplate`?
    private static RestTemplate createRestTemplate(){
        // is it ok to create a new instance of HttpComponentsClientHttpRequestFactory everytime?
       HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
       requestFactory.setReadTimeout(READ_TIME_OUT);
       requestFactory.setConnectTimeout(CONNECTION_TIME_OUT);
       return new RestTemplate(requestFactory);
     }

    public String getData() {
        Future future = executor.submit(new Task(restTemplate));
        String response = null;

        try {
            response = future.get(500, TimeUnit.MILLISECONDS);
        } catch (TimeoutException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        return response;
    }
}


Here is my Task class which implements the Callable interface and uses the RestTemplate:

```
class Task implements Callable {

private RestTemplate restTemplate;

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

public String call() throws Exception {

String

Solution

Will you have many instances of TimeoutThreadExample in your real application? If not, then the restTemplate field will be better non-static, initialized in the constructor:

private final RestTemplate restTemplate;

public TimeoutThreadExample() {
    HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
    requestFactory.setReadTimeout(READ_TIME_OUT);
    requestFactory.setConnectTimeout(CONNECTION_TIME_OUT);
    restTemplate = new RestTemplate(requestFactory);
}


On the other hand, if you will have many instances of TimeoutThreadExample, then it will be better to make restTemplate static, and initialize it in a static initializer block instead of using a method:

private static final RestTemplate restTemplate;

static {
    HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
    requestFactory.setReadTimeout(READ_TIME_OUT);
    requestFactory.setConnectTimeout(CONNECTION_TIME_OUT);
    restTemplate = new RestTemplate(requestFactory);
}


As for this question:


// is it ok to create a new instance of HttpComponentsClientHttpRequestFactory everytime?

In both alternatives I offered, the instance is really created only once, so that's ok.


The way I am creating RestTemplate along with HttpComponentsClientHttpRequestFactory is thread safe and efficient?

Initializing static variables is thread safe. And since you're creating RestTemplate and HttpComponentsClientHttpRequestFactory only once, it's efficient too.

Code Snippets

private final RestTemplate restTemplate;

public TimeoutThreadExample() {
    HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
    requestFactory.setReadTimeout(READ_TIME_OUT);
    requestFactory.setConnectTimeout(CONNECTION_TIME_OUT);
    restTemplate = new RestTemplate(requestFactory);
}
private static final RestTemplate restTemplate;

static {
    HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
    requestFactory.setReadTimeout(READ_TIME_OUT);
    requestFactory.setConnectTimeout(CONNECTION_TIME_OUT);
    restTemplate = new RestTemplate(requestFactory);
}

Context

StackExchange Code Review Q#62174, answer score: 3

Revisions (0)

No revisions yet.