Hello Colin,
I assure you the code works fine; although there might be some typos introduced when moving from the code files to the book files. If you would like my original code set, please send me an email message (b_basham@yahoo.com) and I will send you the complete code.
However, you raise some interesting questions, so allow me to talk about these:
Originally posted by Colin Fletcher:
1. The other code uses a group of objects to provide the StreamObject
specifically:
ByteArrayOutputStream
GZIPOutputStream
I also noticed some other websites use the same style, ByteArrayOutputStream, GZIPOutputStream.
Is this way compression or data managling filters "should" work ?
2. Following "finishing" the stream produces "empty html/body tags"..
The "other" code finishes the GZIP Stream, then obtains the bytes rom the ByteArrayOutputStream and then writes them to the HttpServletResponse object.
These two questions are related. What you have found in other peoples compression filters is a common technique, which I call "capture, then transform" technique. This technique uses a ByteArrayOutputStream (BAOS) to capture
all of the content generated by the
JSP or
servlet. Then when control returns to the filter, the filter transforms the complete content all at once (in this case by using a GZIP to compress the content).
The HFS compression filter uses a different technique which I call "transform and send". With this technique the content is being transformed (in this case compression is the transformation)
as the content is being produced by the JSP or servlet. When control returns to the filter all it needs to do is flush the GZIP buffer using the finish method.
There are pros and cons to each of these techniques. The "capture, then transform" technique requires more runtime resources as it needs to buffer
all of the content in memory before the transformation occurs. The "transform and send" technique uses significantly less resources as the transformation occurs as the content is being produced and sent to the client.
3. "write" methods on the stream object.
The sample in the book only implements one. "should we" or "do we have to" implement all the write methods
public void write(int b) throws IOException
public void write(byte b[]) throws IOException
public void write(byte b[], int off, int len) throws IOException
Yes, you could implement all of these methods, but you don't have to so why do more work than is necessary? The answer to this rhetorical question is that in some cases you can gain a performance optimization by specializing each method. This was not important for the code example in HFS.
HTH,
Bryan