tomcat下关于压缩过滤器的代码。具体路径为:C:\apache-tomcat-6.0.35\webapps\examples\WEB-INF\classes\compressionFilters。代码为:
package compressionFilters; import java.io.IOException; import java.util.zip.GZIPOutputStream; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; public class CompressionResponseStream extends ServletOutputStream { //是否启用压缩的临界值 protected int compressThreshold = 0; //临时容纳写入的数据缓冲区 protected byte[] buffer = null; //缓冲区实际写入的数据量 protected int bufferCount = 0; protected GZIPOutputStream gzipstream = null; //当前流对象是否处于关闭状态 protected boolean closed = false; protected int length = -1; //用于返回数据的 Response对象 protected HttpServletResponse response = null; protected ServletOutputStream output = null; public CompressionResponseStream(HttpServletResponse response) throws IOException{ super(); closed = false; this.response = response; this.output = response.getOutputStream(); } //设置启用压缩的临界值,并初始化输出缓冲区 public void setBuffer(int threshold){ compressThreshold = threshold; buffer = new byte[threshold]; } /** * 关闭流对象 */ public void close() throws IOException{ if(closed){ throw new IOException("This output stream has already been closed"); } //如果当前启用的是压缩流,用压缩流刷新缓冲区 if(gzipstream != null){ flushToGZip(); gzipstream.close(); gzipstream = null; }else{ //如果未开启压缩,则用response的默认输出流刷新缓冲区 if(bufferCount > 0){ output.write(buffer, 0, bufferCount); bufferCount = 0; } } } /** * 刷新输出缓冲区 */ public void flush() throws IOException{ if(closed){ throw new IOException("Cannot flush a closed output stream"); } if(gzipstream != null){ gzipstream.flush(); } } public void write(int b) throws IOException { if(closed){ throw new IOException("Cannot write to a closed output stream"); } //如果数据超出了缓冲区(启用压缩的临界值),则启用压缩模式 if(bufferCount >= buffer.length){ flushToGZip(); } //如果没有超出缓冲区,则将数据写入缓冲区 buffer[bufferCount++] = (byte)b; } public void write(byte[] b,int off,int len) throws IOException{ if(closed){ throw new IOException("Cannot write to a closed output stream"); } if(len == 0){ return; } //如果缓冲区能容纳这些数据则写入缓冲区 if(len <= buffer.length - bufferCount){ System.arraycopy(b, off, buffer, bufferCount, len); bufferCount += len; return; } //如果缓冲区剩余空间不住足,则开启压缩流对象 flushToGZip(); //如果清空后的缓冲区能够容纳传送过来的数据,则将数据写入缓冲区 if(len <= buffer.length - bufferCount){ System.arraycopy(b, off, buffer, bufferCount, len); bufferCount += len; return; } //如果缓冲区不能容纳传送进来的数据,则直接将数据写入压缩流对象 writeToGZip(b, off, len); } //刷新压缩流对象的缓冲区 public void flushToGZip() throws IOException{ if(bufferCount > 0){ writeToGZip(buffer, 0, bufferCount); bufferCount = 0; } } public void writeToGZip(byte b[],int off,int len)throws IOException{ //如果压缩流对象为空,这里初始化它 if(gzipstream == null){ response.addHeader("Content-Encoding", "gzip"); gzipstream = new GZIPOutputStream(output); } //将数据听过压缩流对象输出到response的输出流 gzipstream.write(b,off,len); } public boolean closed(){ return closed; } }
package compressionFilters; import java.io.IOException; import java.util.zip.GZIPOutputStream; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; public class CompressionResponseStream extends ServletOutputStream { //是否启用压缩的临界值 protected int compressThreshold = 0; //临时容纳写入的数据缓冲区 protected byte[] buffer = null; //缓冲区实际写入的数据量 protected int bufferCount = 0; protected GZIPOutputStream gzipstream = null; //当前流对象是否处于关闭状态 protected boolean closed = false; protected int length = -1; //用于返回数据的 Response对象 protected HttpServletResponse response = null; protected ServletOutputStream output = null; public CompressionResponseStream(HttpServletResponse response) throws IOException{ super(); closed = false; this.response = response; this.output = response.getOutputStream(); } //设置启用压缩的临界值,并初始化输出缓冲区 public void setBuffer(int threshold){ compressThreshold = threshold; buffer = new byte[threshold]; } /** * 关闭流对象 */ public void close() throws IOException{ if(closed){ throw new IOException("This output stream has already been closed"); } //如果当前启用的是压缩流,用压缩流刷新缓冲区 if(gzipstream != null){ flushToGZip(); gzipstream.close(); gzipstream = null; }else{ //如果未开启压缩,则用response的默认输出流刷新缓冲区 if(bufferCount > 0){ output.write(buffer, 0, bufferCount); bufferCount = 0; } } } /** * 刷新输出缓冲区 */ public void flush() throws IOException{ if(closed){ throw new IOException("Cannot flush a closed output stream"); } if(gzipstream != null){ gzipstream.flush(); } } public void write(int b) throws IOException { if(closed){ throw new IOException("Cannot write to a closed output stream"); } //如果数据超出了缓冲区(启用压缩的临界值),则启用压缩模式 if(bufferCount >= buffer.length){ flushToGZip(); } //如果没有超出缓冲区,则将数据写入缓冲区 buffer[bufferCount++] = (byte)b; } public void write(byte[] b,int off,int len) throws IOException{ if(closed){ throw new IOException("Cannot write to a closed output stream"); } if(len == 0){ return; } //如果缓冲区能容纳这些数据则写入缓冲区 if(len <= buffer.length - bufferCount){ System.arraycopy(b, off, buffer, bufferCount, len); bufferCount += len; return; } //如果缓冲区剩余空间不住足,则开启压缩流对象 flushToGZip(); //如果清空后的缓冲区能够容纳传送过来的数据,则将数据写入缓冲区 if(len <= buffer.length - bufferCount){ System.arraycopy(b, off, buffer, bufferCount, len); bufferCount += len; return; } //如果缓冲区不能容纳传送进来的数据,则直接将数据写入压缩流对象 writeToGZip(b, off, len); } //刷新压缩流对象的缓冲区 public void flushToGZip() throws IOException{ if(bufferCount > 0){ writeToGZip(buffer, 0, bufferCount); bufferCount = 0; } } public void writeToGZip(byte b[],int off,int len)throws IOException{ //如果压缩流对象为空,这里初始化它 if(gzipstream == null){ response.addHeader("Content-Encoding", "gzip"); gzipstream = new GZIPOutputStream(output); } //将数据听过压缩流对象输出到response的输出流 gzipstream.write(b,off,len); } public boolean closed(){ return closed; } }
package compressionFilters; import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; public class CompressionServletResponseWrapper extends HttpServletResponseWrapper { /** * 原始的response对象 */ protected HttpServletResponse origResponse = null; protected static final String info = "CompressionServletResponseWrapper"; /** * response对象的输出流 */ protected ServletOutputStream stream = null; /** * response */ protected PrintWriter writer = null; protected int threshold = 0; protected String contentType = null; public CompressionServletResponseWrapper(HttpServletResponse response) { super(response); origResponse = response; } /** * 设置实体类型 */ public void setContentType(String contentType){ this.contentType = contentType; origResponse.setContentType(contentType); } /** * 设置启用压缩的临界值 * @param threshold 临界值 */ public void setCompressionThreshold(int threshold){ this.threshold = threshold; } public ServletOutputStream createOutputStream() throws IOException{ CompressionResponseStream stream = new CompressionResponseStream(origResponse); stream.setBuffer(threshold); return stream; } //关闭输出对象 public void finishResponse(){ try { if(writer != null){ writer.close(); }else{ if(stream != null){ stream.close(); } } } catch (IOException e) { } } public void flushBuffer() throws IOException{ ((CompressionResponseStream)stream).flush(); } public ServletOutputStream getOutputStream() throws IOException{ //如果字符流打开,则抛出异常 if(writer != null) throw new IllegalStateException("getWriter() has already been called for this response"); if(stream == null) stream = createOutputStream(); return stream; } public PrintWriter getWriter() throws IOException{ if(writer != null){ return (writer); } if(stream != null) throw new IllegalStateException("getOutputStream() has already been called for this response"); stream = createOutputStream(); String charEnc = origResponse.getCharacterEncoding(); if(charEnc != null){ writer = new PrintWriter(new OutputStreamWriter(stream,charEnc)); }else{ writer = new PrintWriter(stream); } return writer; } private static String getCharsetFromContentType(String type){ if(type == null){ return null; } int semi = type.indexOf(":"); if(semi == -1){ return null; } String afterSemi = type.substring(semi + 1); int charsetLocation = afterSemi.indexOf("charset="); if(charsetLocation == -1){ return null; }else{ String afterCharset = afterSemi.substring(charsetLocation + 8); String encoding = afterCharset.trim(); return encoding; } } }