Top 5 solutions for Java Http Clients

 

There are several ways to create an HTTP client in Java. In this tutorial, we will explore five different options for creating an HTTP client in Java, ranging from low-level libraries to high-level frameworks.

java http client example

Use Java built-in HttpURLConnection

This is the simplest solution and it does not require any additional library to be included in your classpath:

URL url = new URL("http://www.acme.com");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setDoOutput(true);
out.flush();
out.close();

You can additionally send parameters along with your HTTP Request:

Map<String, String> params = new HashMap<>();
params.put("key1", "val1");
params.put("key2", "val2");
 
con.setDoOutput(true);
DataOutputStream out = new DataOutputStream(con.getOutputStream());
out.writeBytes(ParameterStringBuilder.getParamsString(parameters));
out.flush();
out.close();

This is not the best option in terms of performance or memory footprint. You should use it only if you have a very old Java environment.

Using Apache HttpComponents HttpClient.

The Apache Commons HttpClient project is well-known to developers but it is now end of life, and is no longer being developed. Its replacement is the Apache HttpComponents project. This project includes the HttpClient and HttpCore modules, which offer better performance and more flexibility.

The following example demonstrates how to process HTTP responses using a response Handler. The use of an HTTP response handler guarantees that the underlying HTTP connection will be released back to the connection manager automatically in all cases.

import java.io.IOException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class ClientWithResponseHandler {

    public final static void main(String[] args) throws Exception {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            HttpGet httpget = new HttpGet("http://www.acme.com");

            System.out.println("Executing request " + httpget.getRequestLine());

            // Create a custom response handler
            ResponseHandler<String> responseHandler = new ResponseHandler<String>() {

                @Override
                public String handleResponse(
                        final HttpResponse response) throws ClientProtocolException, IOException {
                    int status = response.getStatusLine().getStatusCode();
                    if (status >= 200 && status < 300) {
                        HttpEntity entity = response.getEntity();
                        return entity != null ? EntityUtils.toString(entity) : null;
                    } else {
                        throw new ClientProtocolException("Unexpected response status: " + status);
                    }
                }

            };
            String responseBody = httpclient.execute(httpget, responseHandler);
            System.out.println("----------------------------------------");
            System.out.println(responseBody);
        } finally {
            httpclient.close();
        }
    }

}

In order to compile examples using the Http Components library, you need to include in your pom.xml:

<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpclient</artifactId>
  <version>4.5.14</version>
</dependency>

The following code snippet show you how to send POST request with a JSON body using HttpClient. The Http payload in this example is placed in an object called StringEntity:

public void postJson() 
  throws ClientProtocolException, IOException {
    CloseableHttpClient client = HttpClients.createDefault();
    HttpPost httpPost = new HttpPost("http://www.acme.com");
 
    String json = "{"id":1,"name":"Frank"}";
    StringEntity entity = new StringEntity(json);
    httpPost.setEntity(entity);
    httpPost.setHeader("Accept", "application/json");
    httpPost.setHeader("Content-type", "application/json");
 
    CloseableHttpResponse response = client.execute(httpPost);
    client.close();
}

Please note that we have a specialized tutorial on writing high performance Java HTTP Clients with Apache HTTP Client: Writing high performance Java HTTP Client applications

Use Java 11 HttpClient API

The Java 11 HttpClient is a new library introduced in Java 11 for sending HTTP requests and receiving responses. It is part of the java.net.http package and replaces the older java.net.URLConnection library.

One of the main advantages of the Java 11 HttpClient is its modern and efficient design. It supports HTTP/2 and WebSockets, and it has a high-level API that makes it easy to use.

Here is an example of how to use the Java 11 HttpClient to send an HTTP GET request and receive the response:

import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class Example {
    public static void main(String[] args) throws IOException, InterruptedException {
        // Create the HttpClient
        HttpClient httpClient = HttpClient.newHttpClient();

        // Create the HttpRequest
        HttpRequest httpRequest = HttpRequest.newBuilder()
                .uri(URI.create("http://example.com"))
                .GET()
                .build();

        // Send the request and receive the response
        HttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());

        // Print the status code
        System.out.println("Status code: " + httpResponse.statusCode());

        // Print the body of the response
        System.out.println("Response body: " + httpResponse.body());
    }
}

In this example, we create an HTTP client using the newHttpClient() method. Then, we create an HTTP GET request using the HttpRequest.Builder class and the GET() method. Finally, we use the send() method of the HTTP client to send the request and receive the response as a string.

Comparing Java 11 HTTP Client API with Apache HttpComponents

In general terms, the Java 11 HTTP Client API has several advantages compared with Java URL Connection and Apache Http Components:

  • Firstly, the Java 11 HTTP client API has a more modern, fluent API design, with methods that return HTTP request and response builders rather than mutable objects. This makes it easier to build and customize HTTP requests and responses.

  • Then, the Java 11 HTTP client API is fully non-blocking and uses the asynchronous, reactive programming model. This means you can use it with the Java 9+ Flow API to process HTTP responses as a stream of data rather than as individual response objects.

  • Finally, the Java 11 HTTP client API is more efficient than Apache HttpComponents, with a smaller memory footprint and better performance.

Use Unirest HTTP Api

Unirest is a set of lightweight HTTP libraries available in multiple languages, built and maintained by Mashape, who also maintain the open-source API Gateway Kong. Using Unirest can be that simple:

Unirest.post("http://httpbin.org/post")
  .queryString("name", "John")
  .field("surname", "Smith")
  .asJson()

Besides the standard post and get requests, you can also create multipart requests for uploading files: simply pass along a File or an InputStream Object as a field:

HttpResponse<JsonNode> jsonResponse = Unirest.post("http://acme.com/post")
  .header("accept", "application/json")
  .field("parameter", "value")
  .field("file", new File("/tmp/file"))
  .asJson();

Asynchronous requests are supported as well by using anonymous callbacks, or direct method placement::

Future<HttpResponse<JsonNode>> future = Unirest.post("http://acme.com/post")
  .header("accept", "application/json")
  .field("param1", "value1")
  .field("param2", "value2")
  .asJsonAsync(new Callback<JsonNode>() {

    public void failed(UnirestException e) {
        System.out.println("The request has failed");
    }

    public void completed(HttpResponse<JsonNode> response) {
         int code = response.getStatus();
         Map<String, String> headers = response.getHeaders();
         JsonNode body = response.getBody();
         InputStream rawBody = response.getRawBody();
    }

    public void cancelled() {
        System.out.println("The request has been cancelled");
    }

});

You can use Maven by including the library:

<dependency>
    <groupId>com.mashape.unirest</groupId>
    <artifactId>unirest-java</artifactId>
    <version>1.4.9</version>
</dependency>

Also, as Unirest brings in the picture also Apache Http libraries, the following ones must be included in your pom.xml:

<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpclient</artifactId>
  <version>4.3.6</version>
</dependency>
<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpasyncclient</artifactId>
  <version>4.0.2</version>
</dependency>
<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpmime</artifactId>
  <version>4.3.6</version>
</dependency>
<dependency>
  <groupId>org.json</groupId>
  <artifactId>json</artifactId>
  <version>20140107</version>
</dependency>

Using OkHttp

OkHttp is an HTTP client with an eye on efficiency as it provides native HTTP/2 support, Conneciton pooling, transparent GZIP shrinks and response caching.

Using OkHttp is easy. Its request/response API is designed with fluent builders and immutability.
The following code downloads a URL and print its contents as a string:

OkHttpClient client = new OkHttpClient();

String run(String url) throws IOException {
  Request request = new Request.Builder()
      .url(url)
      .build();

  Response response = client.newCall(request).execute();
  return response.body().string();
}

Posting to a Server is also pretty simple. The following example posts a JSON body:

public static final MediaType JSON
    = MediaType.parse("application/json; charset=utf-8");

OkHttpClient client = new OkHttpClient();

String post(String url, String json) throws IOException {
  RequestBody body = RequestBody.create(JSON, json);
  Request request = new Request.Builder()
      .url(url)
      .post(body)
      .build();
  Response response = client.newCall(request).execute();
  return response.body().string();
}

Finally, the list of dependencies is really minimal:

<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>benchmarks</artifactId>
<version>3.12.13</version>
</dependency>

Using JBang to simplify your HTTP Client setup

Finally, it is worth mentioning that you can use JBang scripting language to simplify the creation of the above HTTP Clients. For example, the following jbang HttpClientDemo does not require any project set up:

//usr/bin/env jbang "$0" "$@" ; exit $?
//JAVA 17
//DEPS org.apache.httpcomponents:httpclient:4.2.1

import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

public class HttpClientDemo {
    public static void main(String[] args) throws IOException {
        var httpClient = new DefaultHttpClient();
        var httpGet = new HttpGet("http://www.google.com/search?q=Groovy");

        var httpResponse = httpClient.execute(httpGet);

        try(var writer = new FileOutputStream("result.html")) {
            writer.write(httpResponse.getEntity().getContent().readAllBytes());
        }
    }
}

You can run it just with:

jbang HttpClientDemo.java

To learn more about JBang, check this article: JBang: Create Java scripts like a pro

Conclusion

In this tutorial, you learned how to create an HTTP client in Java using several libraries such as Apache HttpComponents. You saw how to create an HTTP request, execute it, and receive the response. You also learned how to close the HTTP client to release any resources it is holding.

Found the article helpful? if so please follow us on Socials