KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > openedit > servlet > gzip > GzipResponseStream


1 package com.openedit.servlet.gzip;
2
3 import java.io.ByteArrayOutputStream JavaDoc;
4 import java.io.IOException JavaDoc;
5 import java.io.OutputStream JavaDoc;
6 import java.util.zip.GZIPOutputStream JavaDoc;
7
8 import javax.servlet.ServletOutputStream JavaDoc;
9 import javax.servlet.http.HttpServletResponse JavaDoc;
10
11 public class GzipResponseStream extends ServletOutputStream JavaDoc {
12   // abstraction of the output stream used for compression
13
protected OutputStream JavaDoc bufferedOutput = null;
14   // state keeping variable for if close() has been called
15
protected boolean closed = false;
16   // reference to original response
17
protected HttpServletResponse JavaDoc response = null;
18   // reference to the output stream to the client's browser
19
protected ServletOutputStream JavaDoc output = null;
20   // default size of the in-memory buffer
21
private int bufferSize = 50000;
22
23   public GzipResponseStream(HttpServletResponse JavaDoc response) throws IOException JavaDoc {
24     super();
25     closed = false;
26     this.response = response;
27     this.output = response.getOutputStream();
28     bufferedOutput = new ByteArrayOutputStream JavaDoc();
29   }
30
31   public void close() throws IOException JavaDoc {
32     // This hack shouldn't be needed, but it seems to make JBoss and Struts
33
// like the code more without hurting anything.
34
/*
35     // verify the stream is yet to be closed
36     if (closed) {
37       throw new IOException("This output stream has already been closed");
38     }
39     */

40     // if we buffered everything in memory, gzip it
41
if (bufferedOutput instanceof ByteArrayOutputStream JavaDoc) {
42       // get the content
43
ByteArrayOutputStream JavaDoc baos = (ByteArrayOutputStream JavaDoc)bufferedOutput;
44       // prepare a gzip stream
45
ByteArrayOutputStream JavaDoc compressedContent = new ByteArrayOutputStream JavaDoc();
46       GZIPOutputStream JavaDoc gzipstream = new GZIPOutputStream JavaDoc(compressedContent);
47       byte[] bytes = baos.toByteArray();
48       gzipstream.write(bytes);
49       gzipstream.finish();
50       // get the compressed content
51
byte[] compressedBytes = compressedContent.toByteArray();
52       // set appropriate HTTP headers
53
response.setContentLength(compressedBytes.length);
54       response.addHeader("Content-Encoding", "gzip");
55       output.write(compressedBytes);
56       output.flush();
57       output.close();
58       closed = true;
59     }
60     // if things were not buffered in memory, finish the GZIP stream and response
61
else if (bufferedOutput instanceof GZIPOutputStream JavaDoc) {
62       // cast to appropriate type
63
GZIPOutputStream JavaDoc gzipstream = (GZIPOutputStream JavaDoc)bufferedOutput;
64       // finish the compression
65
gzipstream.finish();
66       // finish the response
67
output.flush();
68       output.close();
69       closed = true;
70     }
71   }
72
73   public void flush() throws IOException JavaDoc {
74     if (closed) {
75       throw new IOException JavaDoc("Cannot flush a closed output stream");
76     }
77     bufferedOutput.flush();
78   }
79
80   public void write(int b) throws IOException JavaDoc {
81     if (closed) {
82       throw new IOException JavaDoc("Cannot write to a closed output stream");
83     }
84     // make sure we aren't over the buffer's limit
85
checkBufferSize(1);
86     // write the byte to the temporary output
87
bufferedOutput.write((byte)b);
88   }
89
90   private void checkBufferSize(int length) throws IOException JavaDoc {
91     // check if we are buffering too large of a file
92
if (bufferedOutput instanceof ByteArrayOutputStream JavaDoc) {
93       ByteArrayOutputStream JavaDoc baos = (ByteArrayOutputStream JavaDoc)bufferedOutput;
94       if (baos.size()+length > bufferSize) {
95         // files too large to keep in memory are sent to the client without Content-Length specified
96
response.addHeader("Content-Encoding", "gzip");
97         // get existing bytes
98
byte[] bytes = baos.toByteArray();
99         // make new gzip stream using the response output stream
100
GZIPOutputStream JavaDoc gzipstream = new GZIPOutputStream JavaDoc(output);
101         gzipstream.write(bytes);
102         // we are no longer buffering, send content via gzipstream
103
bufferedOutput = gzipstream;
104       }
105     }
106   }
107   
108   public void write(byte b[]) throws IOException JavaDoc {
109     write(b, 0, b.length);
110   }
111
112   public void write(byte b[], int off, int len) throws IOException JavaDoc {
113     //System.out.println("writing...");
114
if (closed) {
115       throw new IOException JavaDoc("Cannot write to a closed output stream");
116     }
117     // make sure we aren't over the buffer's limit
118
checkBufferSize(len);
119     // write the content to the buffer
120
bufferedOutput.write(b, off, len);
121   }
122
123   public boolean closed() {
124     return (this.closed);
125   }
126   
127   public void reset() {
128     //noop
129
}
130 }
131
Popular Tags