描述:给 IE 浏览器会送的数据 需要进行gzip 压缩这样访问速度快并且省点浏览。
方法:在最后将数据打给浏览器的时候,将response 中的数据全部压缩,在过滤器放行的时候传入一个假 的response提供缓冲区,这样后面的资源都会写入我的缓冲区,缓冲区满了或者请求快结束的时候将缓冲区的数据压缩后写入真的response。 j2se 提供了一个流GZIPOutputStream用于gzip压缩。j2se 提供了一个流ZIPOutputStream用于zip压缩
public class GzipFilter extends HttpFilter {
@Override
public void doFilter(HttpServletRequest request,
HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 包装 response MyResponse
MyResponse myresponse = new MyResponse(response);
// 放行
chain.doFilter(request, myresponse);
// 从 myresponse中取出数据 压缩 写入 真的response,
ByteArrayOutputStream buffer = myresponse.getBuffer();
byte[] bytes = buffer.toByteArray();
System.out.println("压缩前:" + bytes.length);
// gzip 压缩,创建压缩流,通过一个内存流
ByteArrayOutputStream baout = new ByteArrayOutputStream();
//压缩流也是包装流,所有的包装流都有缓冲区。
GZIPOutputStream gout = new GZIPOutputStream(baout);
// 向压缩流写入数据
gout.write(bytes);
gout.close();
// 取出缓存中数据
byte[] gzipBytes = baout.toByteArray();
// 通知浏览器 数据是压缩的
response.setHeader("Content-Encoding", "gzip");
// 将压缩后的数据写给ie浏览器
response.getOutputStream().write(gzipBytes);
}
}
class MyResponse extends HttpServletResponseWrapper {
private ByteArrayOutputStream buffer = new ByteArrayOutputStream();
//为了不调用两次getWriter方法,还是定义一个PrintWriter对象
private PrintWriter pw ;
public MyResponse(HttpServletResponse response) {
super(response);
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
// 返回我们自定义的流,否则就直接写到浏览器了,我们的目的是给一个假的流,让他先往假的流里面写。
//ServletOutputStream是个抽象的类,如果要返回这个类,我们就得自己写个这样的方法
//创建了一个继承抽象类的子类对象并返回
MyOutputStream myOutputStream = new MyOutputStream(buffer);
return myOutputStream;
}
@Override//复写getWriter方法是为了也方便压缩jsp中的数据。因为jsp中用的就是getWriter写入的数据
public PrintWriter getWriter() throws IOException {
// 返回我们自定义的流
if(pw==null) {
MyOutputStream myOutputStream = new MyOutputStream(buffer);
pw = new PrintWriter(new OutputStreamWriter(myOutputStream, "utf-8"));
}
return pw;
}
public ByteArrayOutputStream getBuffer() {
return buffer;
}
}
//定义一个类MyOutputStream来继承抽象类ServletOutputStream
class MyOutputStream extends ServletOutputStream {
// 接收一个缓冲区
private ByteArrayOutputStream buffer;
public MyOutputStream(ByteArrayOutputStream buffer) {
super();
this.buffer = buffer;
}
@Override
public void write(int b) throws IOException {
// 将字节写到哪去,这也是为什么是抽象方法的原因
buffer.write(b);
}
}