ZetCode

Java HttpClient

last modified January 27, 2024

Java HttpClient tutorial shows how to create HTTP requests with HttpClient in Java. In the examples, we create simple GET and POST requests.

HTTP

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

In the examples, we use httpbin.org, which is a freely available HTTP request and response service, and the webcode.me, which is a tiny HTML page for testing.

HttpClient

Java 11 introduced HttpClient library. Before Java 11, developers had to use rudimentary URLConnection, or use third-party library such as Apache HttpClient, or OkHttp.

The Java HTTP Client supports both HTTP/1.1 and HTTP/2. By default the client will send requests using HTTP/2. Requests sent to servers that do not yet support HTTP/2 will automatically be downgraded to HTTP/1.1.

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

There are two ways to create an HttpClient. The code creates new client with default settings.

Java HttpClient status

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

com/zetcode/HttpClientStatus.java
package com.zetcode;

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 HttpClientStatus {

    public static void main(String[] args) throws IOException, InterruptedException {

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

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

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

The example creates a GET request to the webcode.me website and retrives an http response. From the response, we get the status code.

HttpClient client = HttpClient.newHttpClient();

A new HttpClient is created.

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

A new HttpRequest is built. We specify the URI and the request method. (If we do not specify the request method, the default is GET.)

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

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

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

We get the status code with the statusCode method.

Java HttpClient HEAD request

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

com/zetcode/HeadRequest.java
package com.zetcode;

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;

public class HeadRequest {

    public static void main(String[] args) throws IOException, InterruptedException {

        HttpClient client = HttpClient.newHttpClient();

        var request = HttpRequest.newBuilder(URI.create("http://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);
        });
    }
}

The example creates a HEAD request.

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

We build a HEAD request. We use HttpRequest.BodyPublishers.noBody since we do not have any body in the request.

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

We send a request and receive a body.

HttpHeaders headers = response.headers();

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

We get the headers from the response and print them to the console.

$ java HeadRequest.java
accept-ranges: [bytes]
connection: [keep-alive]
content-length: [394]
content-type: [text/html]
date: [Sat, 16 Jul 2022 16:38:11 GMT]
etag: ["61ed305d-18a"]
last-modified: [Sun, 23 Jan 2022 10:39:25 GMT]
server: [nginx/1.6.2]

Java HttpClient GET request

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

com/zetcode/GetRequest.java
package com.zetcode;

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 GetRequest {

    public static void main(String[] args) throws IOException, InterruptedException {

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("http://webcode.me"))
                .build();

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

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

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

HttpClient client = HttpClient.newHttpClient();

A new HttpClient is created with the newHttpClient factory method.

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

We build 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 and retrieve the content of the response and print it to the console. We use HttpResponse.BodyHandlers.ofString since we expect a string HTML response.

Java HttpClient file bodyhandler

With file bodyhandler, we can easily write the response text to a file.

com/zetcode/FileBodyHandler.java
package com.zetcode;

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.Paths;

public class FileBodyHandler {

    public static void main(String[] args) throws IOException, InterruptedException {

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

        var fileName = "src/resources/index.html";

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

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

The example writes the HTML page to src/resources/index.html file.

var fileName = "src/resources/index.html";

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

The file bodyhandler is created with HttpResponse.BodyHandlers.ofFile.

Java HttpClient POST request

The HTTP POST method sends data to the server. It is often used when uploading a file or when submitting a completed web form.

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.9.3</version>
</dependency>

We need the jackson-databind dependency.

com/zetcode/PostRequest.java
package com.zetcode;

import com.fasterxml.jackson.databind.ObjectMapper;

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;

public class PostRequest {

    public static void main(String[] args) throws IOException, InterruptedException {

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

        var objectMapper = new ObjectMapper();
        String requestBody = objectMapper
                .writeValueAsString(values);

        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");
}};

var objectMapper = new ObjectMapper();
String requestBody = objectMapper
        .writeValueAsString(values);

First, we build the request body with the Jackson's ObjectMapper.

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

We build the POST request. With BodyPublishers.ofString we create 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.

{
    "args": {}, 
    "data": "{\"occupation\":\"gardener\",\"name\":\"John Doe\"}", 
    "files": {}, 
    "form": {}, 
    "headers": {
        "Content-Length": "43", 
        "Host": "httpbin.org", 
        "User-Agent": "Java-http-client/12.0.1"
    }, 
    "json": {
        "name": "John Doe", 
        "occupation": "gardener"
    }, 
    ...
    "url": "https://httpbin.org/post"
    }

Java HttpClient redirect

Redirection is a process of forwarding one URL to a different URL. The HTTP response status code 301 Moved Permanently is used for permanent URL redirection; 302 Found for a temporary redirection.

com/zetcode/RedirectEx.java
package com.zetcode;

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

public class RedirectEx {

    public static void main(String[] args) throws IOException, InterruptedException {

        HttpClient client = HttpClient.newBuilder()
                .followRedirects(HttpClient.Redirect.ALWAYS).build();

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

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

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

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

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 is a test URL that redirects the request three times.

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

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

The request is sent and the response status is printed.

Java HttpCliet read favicon

The following example reads a small image from a website.

com/zetcode/ReadFavicon.java
package com.zetcode;

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 ReadFavicon {

    public static void main(String[] args) throws IOException, InterruptedException {

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create("http://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();
            }
        }
    }
}

The example reads a favicon from a website and prints its contents in hexadecimal format.

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

With HttpResponse.BodyHandlers.ofByteArray we read binary data.

byte[] data = response.body();

We get 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 output the bytes in hexadecimal format.

Source

Java HttpClient - language reference

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

Author

My name is Jan Bodnar and I am a passionate programmer with many years of programming experience. I have been writing programming articles since 2007. So far, I have written over 1400 articles and 8 e-books. I have over eight years of experience in teaching programming.

List all Java tutorials.