08-04
16
一个简单的数据压缩过滤器
作者:Java伴侣 日期:2008-04-16
这个小实例使用GZIP压缩的方式回传给浏览器,而IE5和NS6也都有支持Gzip的压缩格式。
这个方法在之前就有人提出过,因为是让网页在输出时经过压缩,可以让传输量变小很多,虽然现在的网络频宽对于用来看网页已经绰绰有余,但是档案大小太大的网页还是会造成一定的影响。
这里是压缩功能的代码:
web.xml中的设定为:
这里主要是为了介绍filter和filter的wrapper机制
此filter会将设定的网页范围全部用gzip压缩过,
然后浏览器将可以直接看压缩的网页。
总结
现在部分WEB服务器已经支持GZIP压缩功能,其中Tomcat配置GZIP压缩最为简单,
本程序使用过滤器来完成页面数据压缩功能是为了适应各种WEB服务器,
可以在不支持GZIP压缩的服务器上对页面数据进行压缩 下面给出一个测试用例:
注意:http://localhost:8080/TestGzip/Index.jsp 这里给出要测试的页面路径
最后可以将压缩后的数据大小与页面大小进行比较一般情况GZIP压缩可以对页面数据压缩30%~40%.
此测试用例需要导入commons-codec-1.3.jar,commons-httpclient-3.0.1.jar,commons-logging.jar 这三个jar包
这个方法在之前就有人提出过,因为是让网页在输出时经过压缩,可以让传输量变小很多,虽然现在的网络频宽对于用来看网页已经绰绰有余,但是档案大小太大的网页还是会造成一定的影响。
这里是压缩功能的代码:
复制内容到剪贴板 程序代码
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();
}
}
}
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>
/*
<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();
}
}
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();
}
}
最后可以将压缩后的数据大小与页面大小进行比较一般情况GZIP压缩可以对页面数据压缩30%~40%.
此测试用例需要导入commons-codec-1.3.jar,commons-httpclient-3.0.1.jar,commons-logging.jar 这三个jar包
评论: 0 | 引用: 0 | 查看次数: 565
发表评论