Search code examples
javamultithreadingapache-httpcomponents

Best way for apache HttpClients using in a multithreaded environment


I need to create a service on the server-side for sending HTTP requests. It works like this:

1. Client sends a request to the server
2. Server uses singleton service for calling 3rd-party API via HTTP.
3. API returns the response
4. Server process this response and return it to the client

It is a synchronized process.

I created service:

public class ApacheHttpClient {

    private final static CloseableHttpClient client = HttpClients.createDefault();

    public String sendPost(String serverUrl, String body) {
        try {
            HttpPost httpPost = new HttpPost(serverUrl);
            httpPost.setEntity(new StringEntity(body));
           
            CloseableHttpResponse response = client.execute(httpPost);

            String responseAsString = EntityUtils.toString(response.getEntity());

            response.close();

            return responseAsString;
        } catch (IOException e) {
            throw new RestException(e);
        }
    }

ApacheHttpClient is a singleton in my system. CloseableHttpClient client is a singleton too.

Question 1: Is it correct to use one instance of CloseableHttpClient client or I should create a new instance for each request? Question 2: When I should close the client? Question 3: This client can process only 2 connections in one time period. Should I use an executor?


Solution

    1. The use of HttpClient instance as a singleton per distinct HTTP service is correct and is in line with the Apache HttpClient best practices. It should not be static, though.

      http://hc.apache.org/httpcomponents-client-5.1.x/migration-guide/preparation.html

    2. One should close HttpClient when releasing the HTTP service. In your case ApacheHttpClient should implement Closeable and close the internal instance of CloseableHttpClient in its #close method.

    3. You probably should not, but it really depends on how exactly your application deals with request execution.