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;
}
}
}