How to return cached gzipped html pages to http servlet request?

I have a small servlet returning several html pages. The content of one of these pages is pretty complex, but changes only every hour or so. However, it is requested often by users. I want to avoid recomputing it at each request.

I was wondering whether it is possible to prepare a gzip-ed version in memory (byte array), and set it as the response to all HTML requests for this page. I would also recompute a new cached gzip-ed version every hour.

If this is possible, how can I do this? Should I use a filter? For the sake of this question, we can assume that all browsers can handle gzip-ed responses. I am looking for a code example.

Upvotes: 1

Views: 1769

Answers (3)

BalusC
BalusC

Reputation: 1109542

Why doing it the hard way?

Open Tomcat's /conf/server.xml, lookup the <Connector> for your HTTP port and edit it as follows to add a new attribute:

<Connector ... compression="on">

Tomcat will then GZIP all responses matching compressableMimeType automagically when the client supports it. All other self-respected webservers have a similar configuration setting.

Upvotes: 3

After quite some googling, this seems to be the solution:

public class MyFilter implements Filter {

    private byte[] my_gzipped_page = ....

    public void doFilter(ServletRequest req, ServletResponse res,
        FilterChain chain) throws IOException, ServletException {

        if (req instanceof HttpServletRequest) {

            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) res;

            String ae = request.getHeader("accept-encoding");

            if (ae != null && ae.indexOf("gzip") != -1) {

                response.addHeader("Content-Length",
                    Integer.toString(my_gzipped_page.length)); 
                response.addHeader("Content-Encoding", "gzip");

                OutputStream output = response.getOutputStream();
                output.write(my_gzipped_page);
                output.flush();
                output.close();

                return;

            } else ...

        }
    }
    ...
}

Upvotes: 5

Nico
Nico

Reputation: 2663

It's not really clear from your question but I'm guessing you're looking for info on how to cache data, rather than how to serve compressed data. Most web servers will automatically compress data if configured to do so, and if the client supplies the necessary headers in the request. In other words, you don't need to compress the page before transmitting it, the server will compress it automatically if possible.

For caching, you can store a processed version of the page either on disk or in memory using for example memcache.

If you know that you'll only need to update the page, say, every hour, you can run a script, for example with crontab, to generate the page every hour and just serve the generated page. That should be fairly straight forward as you don't really need to make special considerations as far as caching on the server side.

On the other hand, if you need to check if the page is stale before deciding wether to use the cached version or a fresh one, it gets a little more complex. For example it's possible that checking if the data is stale is almost as costly as generating the page.

Can't really give a more specific answer without more details.

Upvotes: 0

Related Questions