Friday, August 16, 2024

How to create a REST client in Java? HttpURLConnection and HttpClient Example

Hello guys, if you are wondering how to create a REST client in Java which can send HTTP get and POST request to interact with REST APIs then you have come to the right place. In this article, I am going to teach you how to send HTTP request from Java program and create a REST client without using any third-party library or framework like Spring Framework. Many developer don't know but Java has classes which can send HTTP request and receive HTTP response from day 1, yes I am talking about HttpURLConnection class. While this class is not simple and it's pretty low level you can still use it to interact with any REST APIs if you are working in any Java version where HttpClient is not available, I mean Java version less than JDK 11. 

The new HttpClient library which was introduced in Java 11 and since then it has become my go to tool to send HTTP request form Java program and interact with REST APIs. This class is designed for ease-of-use and it meets modern API standards which promotes reasonable default. 

This design not only makes it easy to create REST client in Java but it also allows for sophisticated low level customization and configuration if you need to. 

Earlier, I have shown many of them in my earlier post about 11 HttpClient Examples but that's for another day. In this tutorial, I will show you how to send HTTP request from Java using old HttpURLConnection and new HttpClient API. 


How to create a simple REST client in Java using HttpURLConnection

First, let's see how to do it using old way before Java 11 using JDK's HttpURLConnection class which is from java.net package. It's always better to go hard way first to see the pain-points, when you do this you will appreciate new HTTP client API even more. 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class RESTClient {

  public static void main(String[] args) throws IOException {
    URL url = new URL("https://jsonplaceholder.typicode.com/posts");
    HttpURLConnection con = (HttpURLConnection) url.openConnection();
    con.setRequestMethod("GET");
    int status = con.getResponseCode();
    BufferedReader in = new BufferedReader(
      new InputStreamReader(con.getInputStream()));
    String inputLine;
    StringBuffer content = new StringBuffer();
    while ((inputLine = in.readLine()) != null) {
      content.append(inputLine);
    }
    in.close();
    con.disconnect();
    System.out.println("Status: " + status);
    System.out.println("Content: " + content.toString());
  }
}

In this example, I am sending a simple GET Request to a website and then just parse the response and extract the status code and content. You can see that its not easy and it takes a lot of line of code to just get response and status code as you need to first read Input Stream and then covert it to String. 

Now, let's see how to do this on new way using HttpClient class. 







How to create REST Client using HttpClient in Java?

As I said, Java 11 introduces a new HttpClient class to simplify making HTTP requests and handle responses. 

Here's an example code to create a simple REST client using Java 11 HttpClient:
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class RESTClient {

  public static void main(String[] args) throws Exception {
    HttpClient client = HttpClient.newHttpClient();
    HttpRequest request = HttpRequest.newBuilder()
      .uri(URI.create("https://jsonplaceholder.typicode.com/posts"))
      .build();
    HttpResponse<String> response = client.send(request, 
HttpResponse.BodyHandlers.ofString());
    System.out.println("Status: " + response.statusCode());
    System.out.println("Content: " + response.body());
  }
}

This code does the same thing as previous code, I mean it makes a GET request to the "https://jsonplaceholder.typicode.com/posts" URL using the HttpClient class, retrieves the response and outputs the response status code and content to the console, but you can see that how easy it is as BodyHandler can handle response for you and it can return reponse as String. You also get a HttpResponse class which can be used to get the status code. 

But, that's nothing as HttpClient is much more powerful and capable. 

Here are some ways to improve the code:

Exception handling
The code doesn't handle exceptions that may occur during the HTTP request or response handling. You can add a try-catch block to handle exceptions and display meaningful error messages.

HTTP request method
Currently, the code makes a GET request. To make other types of requests (e.g. POST, PUT, DELETE), you need to set the request method using the HttpRequest.Builder class.

Request headers
The code doesn't set any request headers. You can add headers to the request using the HttpRequest.Builder class.

Query parameters
The code doesn't set any query parameters. You can add query parameters to the request URI using the HttpRequest.Builder class.

Custom response handling
The code uses the default HttpResponse.BodyHandlers.ofString() handler to get the response body as a string. If you need to handle the response differently (e.g. as a stream), you can use a custom response body handler like ofStream(), ofFile() etc.

Reusable code
The code creates a new HttpClient instance for each request. It's recommended to reuse the HttpClient instance for multiple requests to take advantage of connection pooling and other performance optimizations.

Here's an improved version of the code:

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

public class RESTClient {

  private final HttpClient client;

  public RESTClient() {
    client = HttpClient.newBuilder()
      .build();
  }

  public void sendGetRequest() {
    try {
      HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://jsonplaceholder.typicode.com/posts"))
        .header("Content-Type", "application/json")
        .GET()
        .build();
      HttpResponse<String> response 
  = client.send(request, HttpResponse.BodyHandlers.ofString());
      System.out.println("Status: " + response.statusCode());
      System.out.println("Content: " + response.body());
    } catch (Exception e) {
      System.out.println("Error sending GET request: " 
           + e.getMessage());
    }
  }

  public static void main(String[] args) {
    RESTClient restClient = new RESTClient();
    restClient.sendGetRequest();
  }
}


This code adds exception handling, sets a custom request header, and reuses the HttpClient instance for multiple requests.


What is difference between HttpURLConnection and HttpClient in Java?

As I said, while both can be used to create REST Client in Java there are multiple differences betweehn them , which makes HttpCleint better than HttpURLConnection and it's recommended to use HttpClient whenever its avaiablel.

Now, let's see those differences:

1. API Design (Low Level vs  High Level)
HttpURLConnection is an older and low-level API, whereas HttpClient is a newer and higher-level API. HttpClient provides a more modern and user-friendly interface for making HTTP requests compared to HttpURLConnection.


2. Connection Management
HttpURLConnection does not provide built-in support for connection pooling, which can lead to suboptimal performance for applications making many requests to the same server. HttpClient provides built-in support for connection pooling, which can improve the performance of applications making many requests to the same server.


3. Timeout and Cancellation
HttpURLConnection does not provide easy-to-use support for request timeouts and cancellations. HttpClient provides an easier and more intuitive way to set request timeouts and cancel requests.


4. Response Handling
HttpURLConnection provides a basic interface for handling HTTP responses, which can make it more difficult to handle responses in a flexible and extensible way. HttpClient provides a more flexible and extensible interface for handling HTTP responses, including support for reactive programming and streaming responses.

Java Version
HttpURLConnection has been available since Java 1.1 and is part of the standard Java library. HttpClient was introduced in Java 11 and is part of the standard Java library starting from Java 11.


That's all about how to use HttpClient and HttpURLConnection to create REST Client in Java. As Is said, you can use any of these class to send HTTP Request form Java program and interact with REST API. You can not only send and receive string but also JSON and XML but based on these differences, it's generally recommended to use HttpClient over HttpURLConnection when making HTTP requests in Java 11 and later, as it provides a more modern and user-friendly interface for making HTTP requests.

No comments:

Post a Comment