一下代码 来自pebble-2.3.1

首先是一个过滤器拦截response

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class GZIPFilter implements Filter {

  public void doFilter(ServletRequest req, ServletResponse res,
                       FilterChain chain) throws IOException, ServletException {

      HttpServletRequest request = (HttpServletRequest) req;
      HttpServletResponse response = (HttpServletResponse) res;

      String ae = request.getHeader("Accept-Encoding");
      if (ae != null && ae.indexOf("gzip") != -1) {
        GZIPResponseWrapper wrappedResponse = new GZIPResponseWrapper(response);
        chain.doFilter(req, wrappedResponse);
        wrappedResponse.finishResponse();
      } else {
        chain.doFilter(req, res);
      }
  }

  public void init(FilterConfig filterConfig) {
  }

  public void destroy() {
  }

}

 GZIPResponseWrapper 类继承 HttpServletResponseWrapper,主要重写getOutputStream() ,getWriter() 方法

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

public class GZIPResponseWrapper extends HttpServletResponseWrapper {

  protected HttpServletResponse wrappedResponse = null;
  protected ServletOutputStream stream = null;
  protected PrintWriter writer = null;

  public GZIPResponseWrapper(HttpServletResponse response) {
    super(response);
    wrappedResponse = response;
  }

  public ServletOutputStream createOutputStream() throws IOException {
    return (new GZIPResponseStream(wrappedResponse));
  }

  public void finishResponse() {
    try {
      if (writer != null) {
        writer.close();
      } else {
        if (stream != null) {
          stream.close();
        }
      }
    } catch (IOException e) {
    }
  }

  public void flushBuffer() throws IOException {
    stream.flush();
  }

  public ServletOutputStream getOutputStream() throws IOException {
    if (writer != null) {
      throw new IllegalStateException("getWriter() has already been called!");
    }

    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!");
    }

    stream = createOutputStream();
    writer = new PrintWriter(new OutputStreamWriter(stream, "UTF-8"));
    return (writer);
  }

  public void setContentLength(int length) {
  }

}


 GZIPResponseStream 继承 ServletOutputStream,主要重写write方法

import java.io.*;
import java.util.zip.GZIPOutputStream;
import javax.servlet.*;
import javax.servlet.http.*;

public class GZIPResponseStream extends ServletOutputStream {

  protected ByteArrayOutputStream baos = null;
  protected GZIPOutputStream gzipstream = null;
  protected boolean closed = false;
  protected HttpServletResponse response = null;
  protected ServletOutputStream output = null;

  public GZIPResponseStream(HttpServletResponse response) throws IOException {
    closed = false;
    this.response = response;
    this.output = response.getOutputStream();
    baos = new ByteArrayOutputStream();
    gzipstream = new GZIPOutputStream(baos);
  }

  public void close() throws IOException {
    if (closed) {
      throw new IOException("This output stream has already been closed");
    }
    gzipstream.finish();
    gzipstream.flush();
    gzipstream.close();

    byte[] bytes = baos.toByteArray();
    response.setContentLength(bytes.length);
    response.addHeader("Content-Encoding", "gzip");
    output.write(bytes);
    output.flush();
    output.close();
    closed = true;
  }

  public void flush() throws IOException {
    if (closed) {
      throw new IOException("Cannot flush a closed output stream");
    }
    gzipstream.flush();
  }

  public void write(int b) throws IOException {
    if (closed) {
      throw new IOException("Cannot write to a closed output stream");
    }
    gzipstream.write((byte) b);
  }

  public void write(byte b[]) throws IOException {
    write(b, 0, b.length);
  }

  public void write(byte b[], int off, int len) throws IOException {
    if (closed) {
      throw new IOException("Cannot write to a closed output stream");
    }
    gzipstream.write(b, off, len);
  }

  public boolean closed() {
    return (this.closed);
  }

  public void reset() {
  }

}

 

GZIPOutputStream 说明 来自 JDK API 1.6.0 中文版

public class GZIPOutputStream
extends DeflaterOutputStream

此类为使用 GZIP 文件格式写入压缩数据实现流过滤器。

 

 


字段摘要
protected  CRC32 crc
          未压缩数据的 CRC-32 。
 
从类 java.util.zip.DeflaterOutputStream 继承的字段
buf, def
 
从类 java.io.FilterOutputStream 继承的字段
out
 
构造方法摘要
GZIPOutputStream(OutputStream out)
          使用默认缓冲区大小创建新的输出流。
GZIPOutputStream(OutputStream out, int size)
          使用指定缓冲区大小创建新的输出流。
 
方法摘要
 void finish()
          完成将压缩数据写入输出流的操作,无需关闭底层流。
 void write(byte[] buf, int off, int len)
          将字节数组写入压缩输出流。
 
从类 java.util.zip.DeflaterOutputStream 继承的方法
close, deflate, write
 
从类 java.io.FilterOutputStream 继承的方法
flush, write
 
从类 java.lang.Object 继承的方法
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

字段详细信息

crc

protected CRC32 crc
未压缩数据的 CRC-32 。

 

构造方法详细信息

GZIPOutputStream

public GZIPOutputStream(OutputStream out,
                        int size)
                 throws IOException
使用指定缓冲区大小创建新的输出流。

 

参数:
out - 输出流
size - 输出缓冲区大小
抛出:
IOException - 如果发生 I/O 错误。
IllegalArgumentException - 如果大小为 <= 0

GZIPOutputStream

public GZIPOutputStream(OutputStream out)
                 throws IOException
使用默认缓冲区大小创建新的输出流。

 

参数:
out - 输出流
抛出:
IOException - 如果发生 I/O 错误。

方法详细信息

write

public void write(byte[] buf,
                  int off,
                  int len)
           throws IOException
将字节数组写入压缩输出流。在写入所有字节前,此方法将阻塞。

 

覆盖:
DeflaterOutputStream 中的 write
参数:
buf - 要写入的数据
off - 数据的初始偏移量
len - 数据的长度
抛出:
IOException - 如果发生 I/O 错误
另请参见:
FilterOutputStream.write(int)

finish

public void finish()
            throws IOException
完成将压缩数据写入输出流的操作,无需关闭底层流。对同一输出流相继应用多个过滤器时使用此方法。

 

覆盖:
DeflaterOutputStream 中的 finish
抛出:
IOException - 如果发生 I/O 错误
评论
发表评论

您还没有登录,请登录后发表评论

LEICHAO
搜索本博客
我的相册
A685826d-c23b-32fa-ad99-59caf41ba18a-thumb
prototype_ajax
共 2 张
存档
最新评论