Response Compression with Custom Servlet Filters

One major drawback of the response-manipulating servlet filters that I have showcased on this site is that the delivered compression functionality needed to be disabled for them to work.  This involved unchecking the “Compress Responses” checkbox on the web profile configuration page in the PIA.  Disabling this functionality causes a performance impact because of the resulting large response messages that get sent to the client.  I recently got a comment from Jonathan Rehm explaining how he has achieved GZIP compression within a custom servlet filter.  I decided to integrate the code he shared into a standalone response compression servlet filter.  This servlet filter can co-exist with any other custom filters that you may have deployed.  I will demonstrate how to deploy this custom response compression servlet filter in this post.

CLICK HERE to download the project.

Extract the zip and you should see the following files:

Compression Filter Files

Take the folder named “custom” and place it in the following directory:

%PS_CFG_HOME%\webserv\*your_domain_name*\applications\peoplesoft\PORTAL.war\WEB-INF\classes\com\peoplesoft\pt

Class Files

Navigate to and open up the web.xml file.  The web.xml file is located in the following directory:

%PS_CFG_HOME%\webserv\*your_domain_name*\applications\peoplesoft\PORTAL.war\WEB-INF

web.xml File

Copy the text from the downloaded file named “webxml.txt” and paste the text into your web.xml file.  Paste in the text so that it is the first <filter> to show up in the web.xml file. This compression filter must be placed before any of your custom response-manipulating filters.

Custom Filters

You will need to bounce the web server at this point.

After bouncing the web server, all of the HTTP responses that are being sent to the client should be getting compressed via this custom filter. This is true even for responses that may be getting manipulated by some other custom filters such as a data masking filter or a global script injection filter.  Here is an example of a response message that got sent to a client with the compression filter disabled:

Compression Disabled

Notice how large the response body of the message is.  Now here is the same request with this custom servlet filter enabled:

Compression Enabled

Notice how the response body of this message is significantly smaller (by 86.2%) than the non-compressed version.

With this custom compression filter enabled, it does not matter if the web profile is configured to compress responses.  This custom compression filter will compress responses regardless.  So the following box on the web profile configuration page in the PIA can be checked or unchecked.

Web Profile

A nice enhancement to this solution would be to read in the web server properties file that contains the “Compress Responses” boolean and to disable/enable the custom compression filter accordingly.  As for now this “Compress Responses” value is disregarded.

So you may be wondering: How does this custom filter override the delivered compression functionality?  The answer is by using the HttpServletRequestWrapper class to wrap the original request message that was sent from the client. The original request message will contain the Accept-Encoding header that specifies the type of encoding that the browser is capable of receiving. Since the delivered compression functionality occurs within the actual servlet, the Accept-Encoding header is what the servlet will look at to determine if compression should be performed or not.  What this custom wrapped request does is it spoofs the Accept-Encoding header to null. This means that when the servlet receives the wrapped request, it does not perform compression because the Accept-Encoding header is null. This results in the servlet to send a non-compressed response message back down the filter chain.  That means when a custom response-manipulating servlet filter receives the response message, it can easily modify the response body of the message since it is not compressed. With this custom response compression filter being first in the order specified in the web.xml file,  it will be the last filter to touch the response message.  What this filter does is it references the Accept-Encoding header of the original request message and it compresses the response accordingly.

It is worth noting that this filter is only capable of encoding responses with GZIP.  This means that if a client does not specify GZIP as an acceptable encoding scheme in the Accept-Encoding header, then no compression will be performed.

Leave a Reply

Your email address will not be published.