ZetCode

Java HttpClient

Last modified: March 20, 2025

In this article, we demonstrate how to create HTTP requests using HttpClient in Java. In the examples, we construct simple GET and POST requests.

HTTP

The Hypertext Transfer Protocol (HTTP) is an application protocol for distributed, collaborative, hypermedia information systems. HTTP serves as the foundation for data communication on the World Wide Web.

In these examples, we utilize httpbin.org, a freely available HTTP request and response service, and webcode.me, a small HTML page designed for testing purposes.

HttpClient

Java 11 introduced the HttpClient library. Prior to Java 11, developers relied on the basic URLConnection or third-party libraries such as Apache HttpClient or OkHttp.

The Java HTTP Client supports both HTTP/1.1 and HTTP/2. By default, the client sends requests using HTTP/2. Requests to servers that do not support HTTP/2 are automatically downgraded to HTTP/1.1.

client = HttpClient.newHttpClient();
client = HttpClient.newBuilder().build();

There are two methods to create an HttpClient. This code generates a new client with default settings.

HttpClient Status

In the first example, we check the status of a web page.

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

void main() throws IOException, InterruptedException {

    try (HttpClient client = HttpClient.newHttpClient()) {

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://webcode.me"))
                .GET() // GET is default
                .build();

        HttpResponse<Void> response = client.send(request,
                HttpResponse.BodyHandlers.discarding());

        System.out.println(response.statusCode());
    }
}

This example creates a GET request to the webcode.me website and retrieves an HTTP response. From the response, we extract the status code.

HttpClient client = HttpClient.newHttpClient();

A new HttpClient instance is created.

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("http://webcode.me"))
    .GET() // GET is default
    .build();

A new HttpRequest is constructed. We specify the URI and the request method. (If the method is unspecified, GET is used by default.)

HttpResponse<Void> response = client.send(request,
    HttpResponse.BodyHandlers.discarding());

We send the request. As we are not interested in the response body, we discard it using HttpResponse.BodyHandlers.discarding.

System.out.println(response.statusCode());

We retrieve the status code using the statusCode method.

HEAD Request

A HEAD request is a GET request without a message body.

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

void main() throws IOException, InterruptedException {

    try (HttpClient client = HttpClient.newHttpClient()) {

        var request = HttpRequest.newBuilder(URI.create("https://webcode.me"))
                .method("HEAD", HttpRequest.BodyPublishers.noBody())
                .build();

        HttpResponse<Void> response = client.send(request,
                HttpResponse.BodyHandlers.discarding());

        HttpHeaders headers = response.headers();

        headers.map().forEach((key, values) -> {
            System.out.printf("%s: %s%n", key, values);
        });
    }
}

This example constructs a HEAD request.

var request = HttpRequest.newBuilder(URI.create("https://webcode.me"))
    .method("HEAD", HttpRequest.BodyPublishers.noBody())
    .build();

We create a HEAD request. We use HttpRequest.BodyPublishers.noBody since the request contains no body.

HttpResponse<Void> response = client.send(request,
    HttpResponse.BodyHandlers.discarding());

We send the request and receive a response.

HttpHeaders headers = response.headers();

headers.map().forEach((key, values) -> {
    System.out.printf("%s: %s%n", key, values);
});

We obtain the headers from the response and display them on the console.

$ java Main.java
accept-ranges: [bytes]
connection: [keep-alive]
content-length: [395]
content-type: [text/html]
date: [Wed, 09 Oct 2024 13:22:09 GMT]
etag: ["64f33c9f-18b"]
last-modified: [Sat, 02 Sep 2023 13:46:07 GMT]
server: [nginx/1.18.0 (Ubuntu)]

GET Request

The HTTP GET method requests a representation of a specified resource. Requests using GET should only retrieve data.

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

void main() throws IOException, InterruptedException {

    try (HttpClient client = HttpClient.newHttpClient()) {

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://webcode.me"))
                .build();

        HttpResponse<String> response = client.send(request,
                HttpResponse.BodyHandlers.ofString());

        System.out.println(response.body());
    }
}

We generate a GET request to the webcode.me webpage.

try (HttpClient client = HttpClient.newHttpClient()) {

A new HttpClient is instantiated with the newHttpClient factory method.

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://webcode.me"))
    .build();

We construct a synchronous request to the webpage. The default method is GET.

HttpResponse<String> response = client.send(request,
    HttpResponse.BodyHandlers.ofString());

System.out.println(response.body());

We send the request, retrieve the response content, and print it to the console. We use HttpResponse.BodyHandlers.ofString since we expect an HTML string response.

File BodyHandler

With a file body handler, we can conveniently save the response text to a file.

Main.java
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
import java.nio.file.Paths;

void main() throws IOException, InterruptedException {

    try (HttpClient client = HttpClient.newHttpClient()) {

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://webcode.me"))
                .GET() // GET is default
                .build();

        String fileName = "src/main/resources/index.html";

        HttpResponse<Path> response = client.send(request,
                HttpResponse.BodyHandlers.ofFile(Paths.get(fileName)));

        System.out.println(response.statusCode());
    }
}

This example saves the HTML page to src/main/resources/index.html.

String fileName = "src/main/resources/index.html";

HttpResponse<Path> response = client.send(request,
        HttpResponse.BodyHandlers.ofFile(Paths.get(fileName)));

The file body handler is created using HttpResponse.BodyHandlers.ofFile.

POST Request

The HTTP POST method transmits data to the server. It is commonly used for uploading files or submitting completed web forms.


    com.google.code.gson
    gson
    2.11.0

We require the gson dependency.

Main.java
import com.google.gson.Gson;

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

void main() throws IOException, InterruptedException {

    var values = new HashMap<String, String>() {{
        put("name", "John Doe");
        put("occupation", "gardener");
    }};

    Gson gson = new Gson();
    String requestBody = gson.toJson(values);

    try (HttpClient client = HttpClient.newHttpClient()) {

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://httpbin.org/post"))
                .POST(HttpRequest.BodyPublishers.ofString(requestBody))
                .build();

        HttpResponse<String> response = client.send(request,
                HttpResponse.BodyHandlers.ofString());

        System.out.println(response.body());
    }
}

We send a POST request to the https://httpbin.org/post page.

var values = new HashMap<String, String>() {{
    put("name", "John Doe");
    put("occupation", "gardener");
}};

Gson gson = new Gson();
String requestBody = gson.toJson(values);

First, we construct the request body using Gson.

try (HttpClient client = HttpClient.newHttpClient()) {
    
    HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://httpbin.org/post"))
            .POST(HttpRequest.BodyPublishers.ofString(requestBody))
            .build();
    ...
}

We create the POST request. With BodyPublishers.ofString, we generate a new BodyPublisher. It converts high-level Java objects into a flow of byte buffers suitable for sending as a request body.

HttpResponse<String> response = client.send(request,
        HttpResponse.BodyHandlers.ofString());

System.out.println(response.body());

We send the request and retrieve the response.

HttpClient Redirect

Redirection involves forwarding one URL to another. The HTTP response status code 301 Moved Permanently indicates a permanent URL redirection, while 302 Found signifies a temporary redirection.

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

// toggle HttpClient.Redirect.ALWAYS / HttpClient.Redirect.NEVER

void main() throws IOException, InterruptedException {

    try (HttpClient client = HttpClient.newBuilder()
            .followRedirects(HttpClient.Redirect.ALWAYS).build()) {

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://httpbin.org/redirect/3"))
                .GET()
                .build();

        HttpResponse<Void> response = client.send(request,
                HttpResponse.BodyHandlers.discarding());

        System.out.println(response.statusCode());
    }
}

In this example, we send a request that is redirected.

try (HttpClient client = HttpClient.newBuilder()
        .followRedirects(HttpClient.Redirect.ALWAYS).build()) {
    ...
}

To configure redirection, we use the followRedirects method.

HttpRequest request = HttpRequest.newBuilder()
        .uri(URI.create("https://httpbin.org/redirect/3"))
        .GET()
        .build();

The https://httpbin.org/redirect/3 URL is a test endpoint that redirects the request three times.

HttpResponse<Void> response = client.send(request,
        HttpResponse.BodyHandlers.discarding());

System.out.println(response.statusCode());

The request is sent, and the response status is displayed.

HttpClient Read Favicon

The following example retrieves a small image from a website.

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

void main() throws IOException, InterruptedException {

    try (HttpClient client = HttpClient.newHttpClient()) {

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("https://webcode.me/favicon.ico"))
                .build();

        HttpResponse<byte[]> response = client.send(request,
                HttpResponse.BodyHandlers.ofByteArray());

        byte[] data = response.body();

        int i = 0;
        for (byte c : data) {

            System.out.printf("%02x ", c);

            i++;

            if (i % 10 == 0) {

                System.out.println();
            }
        }
    }
}

This example fetches a favicon from a website and prints its contents in hexadecimal format.

HttpResponse<byte[]> response = client.send(request,
    HttpResponse.BodyHandlers.ofByteArray());

Using HttpResponse.BodyHandlers.ofByteArray, we read binary data.

byte[] data = response.body();

We extract the array of bytes from the response body.

int i = 0;
for (byte c : data) {

    System.out.printf("%02x ", c);

    i++;

    if (i % 10 == 0) {

        System.out.println();
    }
}

In a for loop, we print the bytes in hexadecimal format.

Source

Java HttpClient - Language Reference

In this article, we have utilized Java HttpClient to create HTTP requests.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than eight years of experience in teaching programming.

View all Java tutorials.