GZIP全站压缩
将压缩后的文本文件,发送给浏览器,减少流量
GZIP压缩的条件:
设置头文件协议:
myresp.setHeader("Content-Encoding", "gzip");
myresp.setContentLength(src.length);
两个主要的类:ByteArrayOutputStream,GZIPOutputStream
采用包装模式对respone加强
主要流程:
共存在两种流,字节流outputStream和字符流PrintWriter
我们需要对respone对象里面的这两种流进行加强,(就是利用包装设计模式,修改两种流的写操作)
过滤器:
将response分装好了之后,传到后台读取数据,全部放到我们定义的ByteArrayOutputStream中,然后从中拿出数据进行压缩。采用原装的发送到前台。
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse resp=(HttpServletResponse) response;
Myresponse myresp =new Myresponse(resp);//采用增强类传过去,直接写在里面
chain.doFilter(request, myresp);
//在返回的时候进行压缩就可以了
//首先获得源数据
ByteArrayOutputStream bout=myresp.getBout();
//转成字节数据----zip写需要
byte[] src=bout.toByteArray();
System.out.println("压缩前"+src.length);//统计数量
ByteArrayOutputStream baout =new ByteArrayOutputStream();
GZIPOutputStream zip =new GZIPOutputStream(baout);
//源数据压缩之后写到内存流中baout中
zip.write(src);
//关闭流
zip.close();
//设置http协议
myresp.setHeader("Content-Encoding", "gzip");
myresp.setContentLength(src.length);
byte[] desc=baout.toByteArray();
System.out.println("压缩之后"+desc.length);
OutputStream out =resp.getOutputStream();//字符流压缩之后必须以字符流去写
out.write(desc);
}
加强类Myresponse(包装模式)
分别写字节流函数的getOutputStream() 和字符流的getWriter()
//这是增强类,必须包括两个字符流和字节流
class Myresponse extends HttpServletResponseWrapper{
private PrintWriter pw;
ByteArrayOutputStream bout;
public Myresponse(HttpServletResponse response) {
super(response);
}
//字符流,字节写一个类,自己写write函数,写到bout中
public ServletOutputStream getOutputStream() throws IOException {
bout=new ByteArrayOutputStream();//每次都需要新的容器。
return new Myout(bout);
}
//字符流的处理,字符流和字节不同,字符流可以实现IO直接的套接,不能单独写
public PrintWriter getWriter() throws IOException {
bout=new ByteArrayOutputStream();//每次都需要新的容器。
pw= new PrintWriter(new OutputStreamWriter(bout, "utf-8"), true);
//直接通过流套接写到内存流,比字节流简单
return pw ;
}
//最后还是需要将这个容器返回出去
public ByteArrayOutputStream getBout() {
if(pw!=null){
pw.close();//字符流必须刷新,否则得不到数据
}
return bout;
}
}
字节流需要从写write函数
构造传参,就bout传到这边进行写操作
/这是字节流的写功能,,,因为printwriter里面可以进行流套接,所以不用另外写一个自己写
class Myout extends ServletOutputStream {
ByteArrayOutputStream bout;
public Myout(ByteArrayOutputStream bout) {
this.bout=bout;
}
@Override
public void write(int b) throws IOException {
bout.write(b);//需要写到内存流里面去
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String str="深刻的骄傲是快乐卡死的快乐撒娇的快乐按键的快乐相处了卡女你说v看见了可那是卡了哪算可怜的那是啥 垃圾都快来asd萨里看到你撒看多了就三次奥斯卡多久";//随便输入的。。。。
// response.getWriter().write(str);
/*
OutputStream out=response.getOutputStream();
byte[] b =str.getBytes("utf-8");
out.write(b);
//字节字符都可以的
*/
PrintWriter pw =response.getWriter();
pw.write(str);
}
当启动服务器是,会拦截压缩,index.jsp
访问超链接到servlet时候,也会压缩
压缩的效率是越大,压缩效率越高。。。
上面的就是过滤器需要实现的功能,可以通过字节,也可以过滤字符,可以实现压缩全站的功能,具体需要压缩什么,可以去web.xml中去配置。(我这里是拦截全部)