I was wondering if there was an easy way to serve GZipped content with Java Servlets. I already have the app up and running so the modifications needed should be too heavy.
I have access to the response object just at the end of the doPost/doGet method, so I'm looking for something like
response.setGzip(true);
It doesn't have to be that easy but it would be ideal.
Thanks a lot
Depending on your container, the container will most likely do this for you. It may do it automatically, or you might need to manually configure it to do it for you. The advantage of this method is zero code changes. And, again, depending on container, you can conditionally enable/disable the compression based on where the request comes from or source browser.
For Tomcat, have a look at the compression attribute on the HTTP config pages (v5.5, v6.0).
Just wanted to let you know what I ended doing.
I made a wrapper of the request class that looks like this:
And then on my
BaseAction
, which is basically a TemplateMethod for other "Actions" I wrap the response like this:I think its clean enough. If you find something that can be improved, please let me know. Thanks everybody for the answers!
If you really, really don't want to fiddle with the Java code any more, you could also consider hooking an Apache server in front of your servlet container.
If you have a lot of static content, this could actually improve performance for you, as the Apache will be a bit faster for static pages than any servlet container. So you'd configure it to only delegate servlet requests to your servlet container on localhost.
Apache has handy built-in options for compressing output. I don't remember how to set them, but it's easy and versatile. It negotiates with browsers about what they can handle, and so on. In case of doubt, Apache will generally be more savvy and up-to-date on compression methods than any Java container.
There are basically 2 ways:
compression
attribute of theConnector
inconf/server.xml
toon
.response.getOutputStream()
in anew GzipOutputStream()
and write to it instead.The first way affects the whole webapp, but this really shouldn't hurt, it's almost zero effort and a big favour for performance. And, more importantingly, as opposed to the second way it actually checks the request headers if the client supports Gzip before using it. When you go for the 2nd way headlessly, then about 10% of the world wide web users wouldn't be able to access your webapplication. This is really not an oneliner task.
You can find here an advanced example of a
FileServlet
which supports under each Gzip and checks that based on the request headers. You may get new insights out of it.This article has the complete (and brief) source code for a ServletFilter that automatically compresses on the fly.
If you are on Tomcat, the connector can do compression for you. This is my configuration,
If you run Apache httpd in front of Tomcat, you should use mod_gzip, which does a much better job.