How to enable gzip compression for content encoding with Jersey (JAX-RS 2.0) client?
Asked Answered
P

4

9

I have a Java application that uses the Jersey implementation of JAX-RS 2.0 and I want to enable gzip compression on the client side. The server has it enabled and I have verified that by looking in Chrome at the "Size/Content" in the Developer Tools for the specific URL the client is using.

I see a lot of information and documentation floating around the web about setting the HTTP Headers with filters and decoding response bodies with interceptors and I cannot decipher what I actually need to code in the client.

I have this code:

private synchronized void initialize() {
    Client client = ClientBuilder.newClient();
    client.register(new HttpBasicAuthFilter(username, password));
    WebTarget targetBase = client.target(getBaseUrl());
    ...
}

What should I add to enable compression?

Perdurable answered 19/3, 2014 at 22:37 Comment(0)
P
5

Modify to look like:

private synchronized void initialize() {
    Client client = ClientBuilder.newClient();
    client.register(new HttpBasicAuthFilter(username, password));
    client.register(GZipEncoder.class);
    WebTarget targetBase = client.target(getBaseUrl());
    ...
    // new lines here:
    Invocation.Builder request = targetBase.request(MEDIA_TYPE);
    request.header(HttpHeaders.ACCEPT_ENCODING, "gzip");
    ...
}

In this example, there are some fields and methods being referenced that I don't include in the example (such as MEDIA_TYPE), you'll have to figure those out yourself. Should be pretty straight forward.

I verified this worked by analyzing the response headers and monitoring the application network usage. I got a 10:1 compression ratio according to the network usage checks I did. That seems about right, yay!

Perdurable answered 20/3, 2014 at 0:21 Comment(3)
Adding the Accept-Encoding header manually is unnecessary; registering GZipEncoder will already accomplish that.Kneel
@Vincent for what version of Jersey? Mine doesn't do that without EncodingFilter.Renfrow
@Renfrow Mine too, I hadn’t realized I had EncodingFilter registered as well :| See EncodingFilter JavaDoc. Manually adding the header not needed anyway.Kneel
R
9

managed to do it with:

private synchronized void initialize() {
    Client client = ClientBuilder.newClient();
    client.register(new HttpBasicAuthFilter(username, password));
    client.register(GZipEncoder.class);
    client.register(EncodingFilter.class);
    WebTarget targetBase = client.target(getBaseUrl());
    ...
}

Pretty much the same as @Jason, but EncodingFilter detects the GzipEncoder for me.

Renfrow answered 20/8, 2014 at 8:43 Comment(1)
Worked for me as well.Komi
P
5

Modify to look like:

private synchronized void initialize() {
    Client client = ClientBuilder.newClient();
    client.register(new HttpBasicAuthFilter(username, password));
    client.register(GZipEncoder.class);
    WebTarget targetBase = client.target(getBaseUrl());
    ...
    // new lines here:
    Invocation.Builder request = targetBase.request(MEDIA_TYPE);
    request.header(HttpHeaders.ACCEPT_ENCODING, "gzip");
    ...
}

In this example, there are some fields and methods being referenced that I don't include in the example (such as MEDIA_TYPE), you'll have to figure those out yourself. Should be pretty straight forward.

I verified this worked by analyzing the response headers and monitoring the application network usage. I got a 10:1 compression ratio according to the network usage checks I did. That seems about right, yay!

Perdurable answered 20/3, 2014 at 0:21 Comment(3)
Adding the Accept-Encoding header manually is unnecessary; registering GZipEncoder will already accomplish that.Kneel
@Vincent for what version of Jersey? Mine doesn't do that without EncodingFilter.Renfrow
@Renfrow Mine too, I hadn’t realized I had EncodingFilter registered as well :| See EncodingFilter JavaDoc. Manually adding the header not needed anyway.Kneel
N
5

In my example (with JAX RS 2.x) and Jersey where multipart is being used, none of the above worked but this did:

Client client = ClientBuilder.newBuilder()
            .register(EncodingFilter.class)
            .register(GZipEncoder.class)
            .property(ClientProperties.USE_ENCODING, "gzip")
            .register(MultiPartFeature.class)
            .register(LoggingFilter.class)
            .build();

Essentially same as the above answers but had to add that one property for "gzip".

Nasia answered 24/2, 2016 at 23:7 Comment(4)
I see you don't have the ACCEPT_ENCODING "gzip" line from the accepted answer. Have you tried to use this instead of the USE_ENCODING "gzip"?Perdurable
The emphasis is on the request and not the response - the ACCEPT_ENCODING is meant for the server to respond with a compressed response since the client is able to accept that.Nasia
I understand the difference. Have you tried ACCEPT_ENCODING? Since your example is missing this I am concerned that it was missing when you tried the other methods mentioned in this question. I have this concern because you say "Essentially same as the above answers but had to add that one property for "gzip"." This implies to me that you just added the property for gzip... not changed it and not removed the ACCEPT_ENCODING. I just want to be sure that ACCEPT_ENCODING didn't work for you.Perdurable
no, it did not work for me for the request to be compressed.Nasia
P
4

Instead of registering EncodingFilter and GZipEncoder individually you can use EncodingFeature directly. With Jersey 2.32 I had problems with incomplete injections and resulting NullPointerExceptions otherwise.

Client client = ClientBuilder.newClient();
client.register(new EncodingFeature("gzip", GZipEncoder.class));
client.register(new HttpBasicAuthFilter(username, password));
WebTarget targetBase = client.target(getBaseUrl());

Note the difference between setting the useEncoding parameter

client.register(new EncodingFeature("gzip", GZipEncoder.class));

or not

client.register(new EncodingFeature(GZipEncoder.class));

is if the initial request by the client is already gzip encoded or if it merely indicates to the server, that it will understand a compressed reply.

Prestidigitation answered 9/12, 2020 at 17:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.