Enable gzip compression in java

If your web infrastructure doesn't handle gziping by default you can enable it by configuring a servlet filter within your java based web application. If you aren't familiar, gzip is a file format used to compress data written to the response and decompress data read from the request. This is a quick hit in reducing the size of the request over the wire whether it is html, JavaScript, css or REST assets especially if teams are focusing on "performance as a feature".

Checking request/response

If you open up chrome dev tools, navigate to the network tab and select a path you can check the headers. For the request check the Accept-Encoding and if the client is able to handle gzip it will be set. If the server returns the content with gzip enabled the Content-Encoding it will contain gzip.

Chrome developer tools network tab

Enable gzip with planetj or ziplet

Ziplet, formally known as planetJ or pjl-comp-filter has been rebranded and is an open source library that contains a J2EE servlet filter which compresses data written to the response. There is multiple compression algorithms with various levels of configuration so be sure to check out the documentation.

Importing dependency

First thing you will want to is import the dependency either with maven, gradle or manually add the jar to your class path.

Ziplet PlanetJ
Maven
<dependency>
    <groupId>com.github.ziplet</groupId>
    <artifactId>ziplet</artifactId>
    <version>2.0.0-SNAPSHOT</version>
</dependency>
<dependency>
    <groupId>net.sourceforge.pjl-comp-filter</groupId>
    <artifactId>pjl-comp-filter</artifactId>
    <version>1.6.4</version>
</dependency>
Gradle
'com.github.ziplet:ziplet:2.0.0'
'net.sourceforge.pjl-comp-filter:pjl-comp-filter:1.6.4'

Add the following deployment descriptor

Once you have imported the dependency, you will want to add the following entries to your web.xml deployment descriptor. Another option is to configure filter programmatically in spring and servlet 3.0. If you are using pjl-comp-filter substitute com.planetj.servlet.filter.compression.CompressingFilter for the ziplet classes below.

<filter>
        <filter-name>CompressingFilter</filter-name>
        <filter-class>com.github.ziplet.filter.compression.CompressingFilter</filter-class>
    </filter>

<filter-mapping>
    <filter-name>CompressingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Verifying compression is enabled

How do you make sure that the compression is working? First check the request and response within chrome dev tools as shown above. Another option is to configure the servlet filter with initialization parameter and value. When passing in debug=true the filter will log additional information to the servlet log. When setting to true, be sure to update when deploying in a production environment as it could add unnecessary overhead.

 <filter>
    <filter-name>CompressingFilter</filter-name>
    <filter-class>com.github.ziplet.filter.compression.CompressingFilter</filter-class>
    <init-param>
        <param-name>debug</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>

Next create a statistics.jsp and drop it into the root of your web application. It will display values from the CompressionFilterStats such as total number of request/response compressed, compression ratio and key statistics.

<%@ page import="com.github.ziplet.filter.compression.*" %>
<html>
<head>
<title>WAR Status</title>
</head>
<body>
<%
CompressingFilterStats stats = (CompressingFilterStats)application.getAttribute(CompressingFilterStats.STATS_KEY);
%>

<h4>GZIP Servlet Statistics (com.github.ziplet.filter.compression.CompressingFilter)</h4>
<table border="1">
<tr><td>resp num compressed</td><td><%= stats.getNumResponsesCompressed() %></td></tr>
<tr><td>resp num not compressed</td><td><%= stats.getTotalResponsesNotCompressed() %></td></tr>
<tr><td>resp input bytes</td><td><%= stats.getResponseInputBytes() %></td></tr>
<tr><td>resp compressed out bytes</td><td><%= stats.getResponseCompressedBytes() %></td></tr>
<tr><td>resp mean compression ratio</td><td><%= stats.getResponseAverageCompressionRatio() %></td></tr>
<tr><td>req num compressed</td><td><%= stats.getNumRequestsCompressed() %></td></tr>
<tr><td>req num not compressed</td><td><%= stats.getTotalRequestsNotCompressed() %></td></tr>
<tr><td>req input bytes</td><td><%= stats.getRequestInputBytes() %></td></tr>
<tr><td>req compressed out bytes</td><td><%= stats.getRequestCompressedBytes() %></td></tr>
<tr><td>req mean compression ratio</td><td><%= stats.getRequestAverageCompressionRatio() %></td></tr>
</table>
</body>
</html>