J2EE的压缩输出流的过滤器实现(来自于Head first Servlets and jsp)

来源:互联网 发布:国产篮球鞋知乎 编辑:程序博客网 时间:2024/06/05 08:17
可以应用到html,但不适用于png,mpeg因为它们已经被压缩过了
Accept-Encoding=gzip,deflate
响应中:Vary=Accept-Encoding
         Content-Encoding=gzip
 

package com.example.web:

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

import java.util.zip.GZIPOutputStream;

public class   CompressionFilter implements Filter {

  private ServletContext ctx;

  private FilterConfig cfg;

//覆写此方法只是为了生成日志

  public void init(FilterConfig cfg) throws ServletException {

    this.cfg = cfg;

    ctx = cfg.getServletContext();

    ctx.log(cfg.getFilterName() + “ initialized.”);

  }

  public void doFilter(ServletRequest req,

         ServletResponse resp,

         FilterChain fc)

  throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;

    HttpServletResponse response = (HttpServletResponse) resp;

 

//根据浏览器是否支持来确定

    String valid_encodings = request.getHeader(“Accept-Encoding”);

    if ( valid_encodings.indexOf(“gzip”) > -1 ) {

     

      CompressionResponseWrapper wrappedResp

 = new CompressionResponseWrapper(response);

wrappedResp.setHeader(“Content-Encoding”, “gzip”);

     

      fc.doFilter(request, wrappedResp);

     //参见GZIPOutputStreamapi

      GZIPOutputStream gzos = wrappedResp.getGZIPOutputStream();

      gzos.finish();

     

      ctx.log(cfg.getFilterName() + “: finished the request.”);

    } else {

      ctx.log(cfg.getFilterName() + “: no encoding performed.”);

      fc.doFilter(request, response);

    }

  }

  public void destroy() {

      // nulling out my instance variables

      cfg = null;

      ctx = null;

  }

}

 

package com.example.web;

// Servlet imports

import javax.servlet.http.*;

import javax.servlet.*;

// I/O imports

import java.io.*;

import java.util.zip.GZIPOutputStream;

class   CompressionResponseWrapper extends HttpServletResponseWrapper {

  private GZIPServletOutputStream servletGzipOS = null;

  private PrintWriter pw = null;

  CompressionResponseWrapper(HttpServletResponse resp) {

    super(resp);

  }

//由于使用压缩,此方法不需使用

  public void setContentLength(int len) { }

 

  public GZIPOutputStream getGZIPOutputStream() {

    return this.servletGzipOS.internalGzipOS;

  }

//标识是使用OutputStream还是PrintWriter

private Object streamUsed = null;

  public ServletOutputStream getOutputStream() throws IOException {

//确定要么是用getWriter要么是用getOutputStream不能两个一起用

 

    if ((streamUsed != null) && (streamUsed != pw)) {

      throw new IllegalStateException();

    }

   

    if ( servletGzipOS == null ) {

      servletGzipOS

   = new GZIPServletOutputStream(getResponse()

     .getOutputStream());

      streamUsed = servletGzipOS;

    }

    return servletGzipOS;

  }

  public PrintWriter getWriter() throws IOException {

   

//确定要么是用getWriter要么是用getOutputStream不能两个一起用

    if ( (streamUsed != null) && (streamUsed != servletGzipOS)) {

      throw new IllegalStateException();

    }

   

    if ( pw == null ) {

     

      servletGzipOS

     = new GZIPServletOutputStream(getResponse()

       .getOutputStream());

//注意这里要根据编码格式,应该是在自己的servlet,JSP中确定

// response.setContentType("text/html;charset=gb2312");

//response.setCharacterEncoding("GBK");

//<%@ page contentType="text/html; charset=utf-8" %>

 

      OutputStreamWriter osw = new OutputStreamWriter(servletGzipOS,

                   getResponse().getCharacterEncoding());

     

      pw = new PrintWriter(osw);

      streamUsed = pw;

    }

    return pw;

  }

}

 

class GZIPServletOutputStream extends ServletOutputStream {

  //包访问权限用于CompressionResponseWrapper来调用

  GZIPOutputStream internalGzipOS;

  /** Decorator constructor */

  GZIPServletOutputStream(ServletOutputStream sos) throws IOException {

    this.internalGzipOS = new GZIPOutputStream(sos);

  }

// This method implements the compression decoration by delegating

//the write() call to the GZIP compression stream, which is wrapping

//the original ServletOutputStream, (which in turn is ultimately

//wrapping the TCP network output stream to the client).

  public void write(int param) throws java.io.IOException {

    internalGzipOS.write(param);

  }

}

原创粉丝点击