这是修补的类,有点像每晚构建的,需要对其进行测试。该
JGZipOutputStream班可以在这里找到: 创建使用jzlib
gzip文件
可以在http://www.jcraft.com/jzlib/中找到JZlib
您可以通过在引导程序路径(
-Xbootclasspath/a:)中添加一个小jar 或对tomcat本身进行解压缩/ jar进行修补。
额外的好处是java impl。实际上比本地代码快。
package org.apache.coyote.http11.filters;import java.io.IOException;import java.io.OutputStream;import java.util.zip.GZIPOutputStream;import org.apache.coyote.OutputBuffer;import org.apache.coyote.Response;import org.apache.coyote.http11.OutputFilter;import org.apache.tomcat.util.buf.ByteChunk;import bestsss.util.JGZipOutputStream;import com.jcraft.jzlib.JZlib;public class GzipOutputFilter implements OutputFilter { protected static org.apache.juli.logging.Log log = org.apache.juli.logging.LogFactory.getLog(GzipOutputFilter.class); // ----------------------------------------------------- Instance Variables protected OutputBuffer buffer; protected OutputStream compressionStream = null; protected OutputStream fakeOutputStream = new FakeOutputStream(); // --------------------------------------------------- OutputBuffer Methods @Override public int doWrite(ByteChunk chunk, Response res) throws IOException { if (compressionStream == null) { compressionStream = new JGZipOutputStream(fakeOutputStream, new byte[Math.min(32768, Math.max(2048, Integer.highestoneBit(chunk.getLength()-1)<<1))]); } compressionStream.write(chunk.getBytes(), chunk.getStart(),chunk.getLength()); return chunk.getLength(); } @Override public long getBytesWritten() { return buffer.getBytesWritten(); } // --------------------------------------------------- OutputFilter Methods public void flush() { if (compressionStream != null) { try { if (log.isDebugEnabled()) { log.debug("Flushing the compression stream!"); } compressionStream.flush(); } catch (IOException e) { if (log.isDebugEnabled()) { log.debug("Ignored exception while flushing gzip filter", e); } } } } @Override public void setResponse(Response response) { // NOOP: No need for parameters from response in this filter } @Override public void setBuffer(OutputBuffer buffer) { this.buffer = buffer; } @Override public long end() throws IOException { if (compressionStream == null) { compressionStream = new JGZipOutputStream(fakeOutputStream, new byte[128]); } compressionStream.close(); return ((OutputFilter) buffer).end(); } @Override public void recycle() { // Set compression stream to null compressionStream = null; } // ------------------------------------------- FakeOutputStream Inner Class protected class FakeOutputStream extends OutputStream { protected ByteChunk outputChunk = new ByteChunk(); protected byte[] singleByteBuffer = new byte[1]; @Override public void write(int b) throws IOException { // Shouldn't get used for good performance, but is needed for // compatibility with Sun JDK 1.4.0 singleByteBuffer[0] = (byte) (b & 0xff); outputChunk.setBytes(singleByteBuffer, 0, 1); buffer.doWrite(outputChunk, null); } @Override public void write(byte[] b, int off, int len) throws IOException { outputChunk.setBytes(b, off, len); buffer.doWrite(outputChunk, null); } @Override public void flush() throws IOException {} @Override public void close() throws IOException {} }}


