Ebooks

Java 11 HttpClient tutorial

Java 11 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.

Java 11 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 11 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 11 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.

accept-ranges: [bytes]
connection: [keep-alive]
content-length: [348]
content-type: [text/html]
date: [Fri, 25 Oct 2019 12:05:17 GMT]
etag: ["5d32ffc5-15c"]
last-modified: [Sat, 20 Jul 2019 11:49:25 GMT]
server: [nginx/1.6.2]

This is a sample output.

Java 11 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.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>My html page</title>
</head>
<body>

    <p>
        Today is a beautiful day. We go swimming and fishing.
    </p>
    
    <p>
         Hello there. How are you?
    </p>
    
</body>
</html>

This is the output.

Java 11 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 11 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"
    }

This is the output.

Java 11 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 11 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.

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

List all Java tutorials.