Async content compression & decompression
Starting with HttpClient 5.6 the async transport can transparently compress request bodies and decompress response bodies. The logic lives in the message-exchange layer, so application code keeps working with plain (already decoded) entities.
Capabilities
- Automatic
Accept-Encodingnegotiation when content compression is enabled and the request does not already carry this header. - Transparent response decompression for
Content-Encodingvaluesdeflate,gzip, andx-gzip. - Optional support for
zstdandbr(Brotli) encodings when the corresponding libraries are present on the classpath. - Streaming request compression via
DeflatingAsyncEntityProducerand the codec-specific wrappers (for exampleDeflatingGzipEntityProducer).
Supported codecs and dependencies
Deflate and GZIP are available out of the box.
Zstandard and Brotli are only wired in when their optional dependencies are present:
- Zstandard –
com.github.luben:zstd-jni - Brotli –
com.aayushatharva.brotli4j:brotli4j(plus a matchingbrotli4j-nativeartefact for the target platform)
At runtime the async client checks the classpath and registers the extra codecs without creating a hard dependency on either library.
Basic usage – transparent response decompression
By default async clients send an Accept-Encoding header and automatically
decode compressed responses before handing them to the application.
No extra code is required:
try (final CloseableHttpAsyncClient client = HttpAsyncClients.createDefault()) {
client.start();
final SimpleHttpRequest request = SimpleRequestBuilder.get("https://httpbin.org/gzip")
.build();
final Future<Message<HttpResponse, String>> future = client.execute(
SimpleRequestProducer.create(request),
new BasicResponseConsumer<>(new StringAsyncEntityConsumer()),
null);
final Message<HttpResponse, String> message = future.get();
System.out.println("status=" + message.getHead().getCode());
System.out.println("body:\n" + message.getBody());
}
Mapping codecs to examples
The async examples in the org.apache.hc.client5.http.examples package exercise
the same codecs that are registered in ContentCompressionAsyncExec:
.register(ContentCoding.GZIP.token(), InflatingGzipDataConsumer::new)
.register(ContentCoding.X_GZIP.token(), InflatingGzipDataConsumer::new)
.register(ContentCoding.DEFLATE.token(), d -> new InflatingAsyncDataConsumer(d, null))
// Optional – only when the libraries are present
.register(ContentCoding.ZSTD.token(), InflatingZstdDataConsumer::new)
.register(ContentCoding.BROTLI.token(), InflatingBrotliDataConsumer::new);
The sections below link each ContentCoding token to a concrete runnable
example, in the same spirit as the Observation examples page.
GZIP (gzip, x-gzip)
-
AsyncClientGzipCompressionExample
Demonstrates streaming a request body compressed with GZIP using
DeflatingGzipEntityProducer. The client sends a compressed POST while the async pipeline addsContent-Encoding: gzipautomatically. -
AsyncClientGzipDecompressionExample
Demonstrates transparent GZIP response decompression. The server returns
Content-Encoding: gzip, the async chain wraps the downstream consumer withInflatingGzipDataConsumer, and application code only sees the plain body.
These examples correspond directly to:
.register(ContentCoding.GZIP.token(), InflatingGzipDataConsumer::new)
.register(ContentCoding.X_GZIP.token(), InflatingGzipDataConsumer::new)
DEFLATE (deflate)
-
AsyncClientDeflateCompressionExample
Demonstrates streaming a request body compressed with deflate using
DeflatingAsyncEntityProducerwrapped around an arbitraryAsyncEntityProducer. -
AsyncClientInflateDecompressionExample
Demonstrates transparent deflate response decompression. When the server responds with
Content-Encoding: deflate, the async execution chain wraps the downstream consumer inInflatingAsyncDataConsumer.
These examples correspond to:
.register(ContentCoding.DEFLATE.token(), d -> new InflatingAsyncDataConsumer(d, null))
Zstandard (zstd)
-
AsyncClientZstdCompressionExample
Shows streaming a request body compressed with Zstandard using
DeflatingZstdEntityProducer, backed by thezstd-jnilibrary. -
End-to-end client/server demo where the classic server always responds with
Content-Encoding: zstdand the async client transparently decodes it viaInflatingZstdDataConsumer.
These examples correspond to the optional Zstandard decoder:
.register(ContentCoding.ZSTD.token(), InflatingZstdDataConsumer::new)
Brotli (br)
-
AsyncClientServerBrotliRoundTrip
Async client/server demo using Brotli in both directions: the client sends a Brotli-compressed request and the server responds with a Brotli-compressed body. The example uses
brotli4jon the client side and Commons Compress for server-side decoding/encoding.
This example matches the optional Brotli decoder registration (and the extra
Accept-Encoding: br token):
.register(ContentCoding.BROTLI.token(), InflatingBrotliDataConsumer::new);
// ...
tokens.add(ContentCoding.BROTLI.token());
Together, these examples show how each ContentEncoding registered in
ContentCompressionAsyncExec maps to a concrete usage pattern in the async
client.




