import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
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;
//采用动态代理进行Gzip过滤
public class GzipFilterProxy implements Filter {
public void destroy() {
// TODO Auto-generated method stub
}
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletRequest request = (HttpServletRequest) req;
final HttpServletResponse response = (HttpServletResponse) res;
final ByteArrayOutputStream bout = new ByteArrayOutputStream();
final PrintWriter pw = new PrintWriter(new OutputStreamWriter(bout,
response.getCharacterEncoding()));
chain.doFilter(request, (ServletResponse) Proxy.newProxyInstance(this
.getClass().getClassLoader(), response.getClass()
.getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
String methodname = method.getName();
if (methodname.equals("getOutputStream")) {//如果调用getOutputStream()方法,则返回保存了数据的字节数据流
return new MyServletOutputStream(bout);
} else if (methodname.equals("getWriter")) {//如果调用getWriter()方法,则返回保存了数据的PrintWriter流
return pw;
} else {
return method.invoke(response, args);
}
}
}));
//Pintwriter 存在缓冲,调用之前进行缓存清空,字节缓冲才能才能得到数据
if (pw != null) {
pw.close();
}
byte data[] = bout.toByteArray();
System.out.println("原始大小:" + data.length);
byte[] gzip = gzip(data);
//告诉浏览器获得的数据是压缩后的数据
response.setHeader("content-encoding", "gzip");
response.setHeader("content-length", gzip.length + "");
response.getOutputStream().write(gzip);
}
//进行数据压缩
private byte[] gzip(byte[] data) throws IOException {
ByteArrayOutputStream bout = new ByteArrayOutputStream();
GZIPOutputStream gout = new GZIPOutputStream(bout);
gout.write(data);
gout.close();
return bout.toByteArray();
}
//创建ServletOutputStream子类,覆盖write方法,从而使数据写到字节数组中
class MyServletOutputStream extends ServletOutputStream {
private ByteArrayOutputStream bout;
public MyServletOutputStream(ByteArrayOutputStream bout) {
this.bout = bout;
}
@Override
public void write(int b) throws IOException {
// TODO Auto-generated method stub
bout.write(b);
}
}
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
}