SimpleClientHttpRequestFactory vs HttpComponentsClientHttpRequestFactory for Http Request timeout with RestTemplate?
Asked Answered
A

2

12

I am working on a project in which I need to make a HTTP URL call to my server which is running Restful Service which returns back the response as a JSON String.

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

public class TimeoutThreadExample {

    private ExecutorService executor = Executors.newFixedThreadPool(10);
    private RestTemplate restTemplate = new RestTemplate();

    public String getData() {
        Future<String> 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;
    }
}

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

class Task implements Callable<String> {

    private RestTemplate restTemplate;

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

    public String call() throws Exception {

        String url = "some_url";
        String response = restTemplate.getForObject(url, String.class);

        return response;
    }
}

Problem Statement:

As you can see above, I am using default way of executing the URL using RestTemplate which doesn't use any Http Request timeout so that means internally it is using -1 as the read and connection timeout.

Now what I am looking to do is, I want to set up Http Request timeout using RestTemplate in my above code efficiently. And I am not sure which class I need to use for that, I can see HttpComponentsClientHttpRequestFactory and SimpleClientHttpRequestFactory so not sure which one I need to use?

Any simple example basis on my above code will help me understand better on how to set the Http Request timeout using RestTemplate.

And also does my Http Request timeout value should be less than future timeout value?

  • HttpComponentsClientHttpRequestFactory vs SimpleClientHttpRequestFactory. Which one to use?
  • Does my Http Request timeout value should be less than future timeout value?
Amasa answered 6/9, 2014 at 7:42 Comment(0)
P
16

By default RestTemplate uses SimpleClientHttpRequestFactory which depends on default configuration of HttpURLConnection.

You can configure them by using below attributes:

-Dsun.net.client.defaultConnectTimeout=TimeoutInMiliSec 
-Dsun.net.client.defaultReadTimeout=TimeoutInMiliSec 

If you want to use HttpComponentsClientHttpRequestFactory - it has a connection pooling configuration which SimpleClientHttpRequestFactory does not have.

A sample code for using HttpComponentsClientHttpRequestFactory:

public class TimeoutThreadExample {

    private ExecutorService executor = Executors.newFixedThreadPool(10);
    private static final RestTemplate restTemplate = createRestTemplate();

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

    public String getData() {
        Future<String> 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;
    }
}
Plausive answered 7/9, 2014 at 1:20 Comment(8)
Thanks for suggestion. By any chance do you know which one we are suppose to use? Or we can use any one of those two? And also how would I use requestFactory in my above code base efficiently? I understand from your example how to use it but where do I fit requestFactory in my above code base since I am using DI to pass the RestTemplate.Amasa
It is up to you, but personally in our large scale projects we have used HttpComponentsClientHttpRequestFactory. But I guess there should not be any problem with both approaches. With HttpComponentsClientHttpRequestFactory you can configure more options using your own HttpClient. For using in your codebase, just pass the HttpComponentsClientHttpRequestFactory instance like the code I wrote at the end of my answerPlausive
Sure, I am thinking of using HttpComponentsClientHttpRequestFactory. I didn't understand which instance you want me to pass? If you can provide an example basis on my code base then I would understand better what do you mean by that?Amasa
Please see the updated answer, you need to create a singleton shared instance of RestTemplate since its thread-safe and heavy to be created. PS: I've not tested the code.Plausive
Thanks for edit. Now I understand clearly what you meant earlier. One last question, what is the difference between READ Timeout vs Connection Timeout here?Amasa
connection timeout is about initial connection handshake, read timeout is = if you block the response in the middle of processing the response. ReadTimout is here - hc.apache.org/httpclient-3.x/apidocs/org/apache/commons/…Plausive
Let us continue this discussion in chat.Amasa
I'm using HttpComponentsClientHttpRequestFactory after I got issue with SimpleClientHttpRequestFactory while extracting the 401 exception response body. Below is my sample code, I'm using defaults with HttpComponentsClientHttpRequestFactory and no custom configurations like timeout and custom custom HTTPClient @Bean public RestTemplate restTemplate() { RestTemplate template = new RestTemplate(); template.setRequestFactory(new HttpComponentsClientHttpRequestFactory()); return template; }Rose
E
1

SimpleClientHttpRequestFactory uses the standard JDK's HTTP library, and hence does not support methods like HttpMethod.PATCH. So it's better to use HttpComponentsClientHttpRequestFactory now than change it later when you have to.

Evanthe answered 12/2, 2021 at 8:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.