08-04
16

一个简单的数据压缩过滤器

这个小实例使用GZIP压缩的方式回传给浏览器,而IE5和NS6也都有支持Gzip的压缩格式。
这个方法在之前就有人提出过,因为是让网页在输出时经过压缩,可以让传输量变小很多,虽然现在的网络频宽对于用来看网页已经绰绰有余,但是档案大小太大的网页还是会造成一定的影响。

这里是压缩功能的代码:
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.zip.GZIPOutputStream;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;


public class GZIPEncodeTest implements Filter {

public void init(FilterConfig filterConfig) {
}

public void doFilter(ServletRequest request, ServletResponse response,
   FilterChain chain) throws IOException, ServletException {
  
  String transferEncoding = getGZIPEncoding((HttpServletRequest) request);
  if (transferEncoding == null) {
   chain.doFilter(request, response);
  } else {
   ((HttpServletResponse) response).setHeader("Content-Encoding",
     transferEncoding);
   GZIPEncodableResponse wrappedResponse = new GZIPEncodableResponse(
     (HttpServletResponse) response);
   chain.doFilter(request, wrappedResponse);
   wrappedResponse.flush();
  }
}

public void destroy() {
}

private static String getGZIPEncoding(HttpServletRequest request) {
  String acceptEncoding = request.getHeader("Accept-Encoding");
  if (acceptEncoding == null)
   return null;
  acceptEncoding = acceptEncoding.toLowerCase();
  if (acceptEncoding.indexOf("x-gzip") >= 0) {
   return "x-gzip";
  }
  if (acceptEncoding.indexOf("gzip") >= 0) {
   return "gzip";
  }
  return null;
}

private class GZIPEncodableResponse extends HttpServletResponseWrapper {
  private GZIPServletStream wrappedOut;

  public GZIPEncodableResponse(HttpServletResponse response)
    throws IOException {
   super(response);
   wrappedOut = new GZIPServletStream(response.getOutputStream());
  }

  public ServletOutputStream getOutputStream() throws IOException {
   return wrappedOut;
  }

  private PrintWriter wrappedWriter;

  public PrintWriter getWriter() throws IOException {
   if (wrappedWriter == null) {
    wrappedWriter = new PrintWriter(new OutputStreamWriter(
      getOutputStream(), getCharacterEncoding()));
   }
   return wrappedWriter;
  }

  public void flush() throws IOException {
   if (wrappedWriter != null) {
    wrappedWriter.flush();
   }
   wrappedOut.finish();
  }
}

private class GZIPServletStream extends ServletOutputStream {
  private GZIPOutputStream outputStream;

  public GZIPServletStream(OutputStream source) throws IOException {
   outputStream = new GZIPOutputStream(source);
  }

  public void finish() throws IOException {
   outputStream.finish();
  }

  public void write(byte[] buf) throws IOException {
   outputStream.write(buf);
  }

  public void write(byte[] buf, int off, int len) throws IOException {
   outputStream.write(buf, off, len);
  }

  public void write(int c) throws IOException {
   outputStream.write(c);
  }

  public void flush() throws IOException {
   outputStream.flush();
  }

  public void close() throws IOException {
   outputStream.close();
  }
}
}


web.xml中的设定为:
<filter>
     <description>Here is  'response to data compression' filters  </description>
     <filter-name>GZIPEncoder   </filter-name>
     <filter-class>com.jsptw.filter.GZIPEncodeFilter</filter-class>
</filter>

<filter-mapping>
      <filter-name>GZIPEncoder</filter-name>
      <url-pattern>/*</url-pattern>
</filter-mapping>

/*



这里主要是为了介绍filter和filter的wrapper机制
此filter会将设定的网页范围全部用gzip压缩过,
然后浏览器将可以直接看压缩的网页。

总结

现在部分WEB服务器已经支持GZIP压缩功能,其中Tomcat配置GZIP压缩最为简单,
本程序使用过滤器来完成页面数据压缩功能是为了适应各种WEB服务器,
可以在不支持GZIP压缩的服务器上对页面数据进行压缩  下面给出一个测试用例:

public static void main(String[] args) throws Exception {
  HttpClient http = new HttpClient();
  GetMethod get = new GetMethod("http://localhost:8080/games/backgroundIndex.jsp");
  try {
   get.addRequestHeader("accept-encoding", "gzip,deflate");
   get
     .addRequestHeader(
       "user-agent",
       "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; Alexa Toolbar; Maxthon 2.0)");
   int er = http.executeMethod(get);
   if (er == 200) {
    String html = get.getResponseBodyAsString();
    System.out.println("页面压缩后的代码:"+html);
    System.out.println("压缩后的页面数据大小:"+html.getBytes().length);
   }
  } finally {
   get.releaseConnection();
  }
}
注意:http://localhost:8080/TestGzip/Index.jsp 这里给出要测试的页面路径

最后可以将压缩后的数据大小与页面大小进行比较一般情况GZIP压缩可以对页面数据压缩30%~40%.

此测试用例需要导入commons-codec-1.3.jar,commons-httpclient-3.0.1.jar,commons-logging.jar 这三个jar包

文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags: 压缩 过滤 filter
相关日志:
评论: 0 | 引用: 0 | 查看次数: 565
发表评论
昵 称:
密 码: 游客发言不需要密码.
内 容:
验证码: 验证码
选 项:
虽然发表评论不用注册,但是为了保护您的发言权,建议您注册帐号.
字数限制 1000 字 | UBB代码 开启 | [img]标签 关闭