0

I have researched enabling gzip encoding for HTTP responses with Jersey. I have found over a decade of answers that differ a lot. They also seem to focus on Jersey 2 and various servers including Tomcat mostly in version 7. I am using Tomcat 10 and Jersey 3 and I am searching for the solution that makes most sense.

What already has been partly working for me is adding a WriterInterceptor. The code looks like this:

@Provider
public class GZIPWriterInterceptor implements WriterInterceptor {
     
    @Override
    public void aroundWriteTo(WriterInterceptorContext context)
                    throws IOException, WebApplicationException {
        final OutputStream outputStream = context.getOutputStream();
        context.setOutputStream(new GZIPOutputStream(outputStream));
        context.proceed();
    }
}

You can find similar code in many answers. On the plus side, this code actually encodes the response as gzip. However, the header is not set correctly, so browsers do not decompress the data. Something like Content-Encoding: gzip seems to be missing.

A different approach seems to be something like this answer. I tried this:

public class Base extends ResourceConfig {
    public Base() {
        register(EncodingFilter.class);
        register(GZipEncoder.class);
        register(DeflateEncoder.class);
        property(ServerProperties.OUTBOUND_CONTENT_LENGTH_BUFFER, 32768);
    }
}

This code is actually executed, I can hit a breakpoint there. I am calling it from web.xml based on this answer. My web.xml looks like this:

<web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_5_0.xsd">
    <servlet>
        <servlet-name>mypackage</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>mypackage</param-value>
        </init-param>


        <!--  This was added. -->
        <init-param>
            <param-name>jakarta.ws.rs.Application</param-name>
            <param-value>mypackage.Base</param-value>
        </init-param>


        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>mypackage</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>
     <listener>
     <listener-class>mypackage.StartStopListener</listener-class>
 </listener>    
</web-app>

Side remark: My version differs from the original answer by using jakarta instead of javax.

However, despite I am using the answer I have linked, which is accepted, I still do not get gzip encoding with this. Also, I do not really care whether the transfer is chunked or not. I'd rather have it compressed, though.

So I went after another partial sentence in the answer:

(...) is entirely the container's discretion.

Thus, I concluded that I had to configure it in Tomcat. That lead me here.

The good news: that actually activated gzip encoding. The minimal code to achieve it needs to be in server.xml:

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" compression="on"/>

However, I checked and I did not need the Jersey filters to do this. I can remove the ResourceConfig and it still works. I am now completely puzzled. I have the following concrete questions:

  1. Is the WriterInterceptor a sensible and up-to-date way of compressing the response, and is there a way to modifiy the headers accordingly?
  2. What are the Jersey filters actually for? I can register them or not, but it does not seem to make a difference.
  3. The method I found of just letting Tomcat handle the compression seems to be superior to everything else I found. I makes me wonder, though. If that is the solution, why are there so many threads and guides on the web that seem to tell a different story? I do not want to ignore all this information without enough understand to know why I am ignoring it.
Tim Lammarsch
  • 161
  • 1
  • 1
  • 10

0 Answers0