How do I handle GZIP or compressed responses with Java 11 HttpClient?

Handling GZIP or compressed responses using the Java 11 HttpClient is straightforward. The HttpClient automatically supports GZIP compression, but you need to specify the Accept-Encoding header in the request to indicate that you accept compressed responses, and it will handle decompression automatically if the server responds with compressed data.

Here’s how you can do it:

Example Code

package org.kodejava.net.http;

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

public class GzipResponseExample {
   public static void main(String[] args) {
      try {
         // Create an HttpClient
         HttpClient httpClient = HttpClient.newHttpClient();

         // Build the HTTP request
         HttpRequest request = HttpRequest.newBuilder()
                 .uri(URI.create("https://example.com"))
                 .header("Accept-Encoding", "gzip") // Indicate support for GZIP responses
                 .build();

         // Send the HTTP request and expect a response
         HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());

         // Print the response body
         System.out.println("Response code: " + response.statusCode());
         System.out.println("Response body: " + response.body());
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

Explanation

  1. HttpClient Creation:
    • An HttpClient instance is created using HttpClient.newHttpClient(), which is reusable.
  2. Request Building:
    • Specify the header Accept-Encoding: gzip to indicate that your client can handle GZIP-compressed responses from the server.
  3. Send Request:
    • The .send() method sends the HTTP request and receives the response. The BodyHandlers.ofString() body handler is used to handle the response body as a decompressed String.
  4. Server-Side Behavior:
    • If the server supports GZIP compression, it might send a response with the header Content-Encoding: gzip.
    • The HttpClient automatically detects and decompresses the GZIP response for you.

Notes:

  • You don’t need to manually handle decompression when using HttpClient. It takes care of the compression and decompression process internally.
  • If the server does not compress the response, the HttpClient simply returns the regular response.

Debugging:

To verify whether the response was compressed:

  • Check the Content-Encoding header in the response. It will show "gzip" if the server sent a compressed response.

Example to log headers:

System.out.println("Headers: " + response.headers());

This approach adheres to modern standards and makes working with compressed HTTP responses simple and efficient in Java!

How do I decompress a GZip file in Java?

In the previous example we have learn how to compress a file in GZIP format. To get the file back to its original version we will now learn how to decompress the gzip file. Just like the previous example, we are also going to use the FileInputStream and FileOutputStream class to read the compressed source file and to write out the decompressed file. While GZipOutputStream was used to create the gzip file, the GZipInputStream is the class that handles the decompression.

Here is your code snippet:

package org.kodejava.util.zip;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;

public class GZipDecompressExample {
    public static void main(String[] args) {
        // GZip input and output file.
        String sourceFile = "output.gz";
        String targetFile = "data-1.txt";

        try (
                // Create a file input stream to read the source file.
                FileInputStream fis = new FileInputStream(sourceFile);

                // Create a gzip input stream to decompress the source
                // file defined by the file input stream.
                GZIPInputStream gzis = new GZIPInputStream(fis);

                // Create file output stream where the decompression result
                // will be stored.
                FileOutputStream fos = new FileOutputStream(targetFile)) {

            // Create a buffer and temporary variable used during the
            // file decompress process.
            byte[] buffer = new byte[1024];
            int length;

            // Read from the compressed source file and write the
            // decompress file.
            while ((length = gzis.read(buffer)) > 0) {
                fos.write(buffer, 0, length);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

How do I compress a file in Gzip format?

In this code example we will learn how to compress a file using the gzip compression. By its nature, gzip can only compress a single file, you can not use it for compressing a directory and all the files in that directory.

Classes that you will be using to compress a file in gzip format includes the GZipOutputStream, FileInputStream and FileOutputStream classes. The steps for compressing a file described in the comments of the code snippet below.

package org.kodejava.util.zip;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.GZIPOutputStream;

public class GZipCompressExample {
    public static void main(String[] args) {
        // GZip input and output file.
        String sourceFile = "data.txt";
        String targetFile = "output.gz";

        try (
                // Create a file input stream of the file that is going to be
                // compressed.
                FileInputStream fis = new FileInputStream(sourceFile);

                // Create a file output stream then write the gzip result into
                // a specified file name.
                FileOutputStream fos = new FileOutputStream(targetFile);

                // Create a gzip output stream object with file output stream
                // as the argument.
                GZIPOutputStream gzos = new GZIPOutputStream(fos)) {

            // Define buffer and temporary variable for iterating the file
            // input stream.
            byte[] buffer = new byte[1024];
            int length;

            // Read all the content of the file input stream and write it
            // to the gzip output stream object.
            while ((length = fis.read(buffer)) > 0) {
                gzos.write(buffer, 0, length);
            }

            // Finish file compressing and close all streams.
            gzos.finish();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}