您现在的位置:首页 >> 前端 >> 内容

过滤器(filter)学习---全站压缩实例

时间:2017/8/9 8:59:30 点击:

  核心提示:过滤器(filter)学习---全站压缩实例。理解过滤器过滤器,顾名思义就是用来过滤的肯定是放在两个东西之间的,最常见的就是放在浏览器和服务器之间的-Servlet只要是客户端请求服务器内的所有网页,...

过滤器(filter)学习---全站压缩实例。

理解过滤器

过滤器,顾名思义就是用来过滤的—肯定是放在两个东西之间的,最常见的就是放在浏览器和服务器之间的—-Servlet
过滤器(filter)学习---全站压缩实例

只要是客户端请求服务器内的所有网页,Servlet.等。中间都可以设置一个过滤器。

如何写过滤器

1.实现一个过滤器的接口

public class GzipFilter implements Filter{

2.实现它的三个方法—用个做实际功能的
过滤器(filter)学习---全站压缩实例

3.在web.xml中配置过滤器参数—用来设置拦截谁的
xml中和Servlet配置一样要配置两个参数
过滤器(filter)学习---全站压缩实例

过滤器(filter)学习---全站压缩实例

其中第一个:filte,和servlet类似


    GzipFilter---改过滤器名字
    cn.hncu.filters.GzipFilter---改过滤器的类再哪
   

第二个:filter-mapping:- FORWARD
- INCLUDE
- REQUEST
- ASYNC
- ERROR

 
    GzipFilter
    /*
    
    
  
  url-pattern---拦截的路径/*表示所有
  dispatche---拦截以下这个中选 FORWARD、INCLUDE、REQUEST、ERROR、ASYNC  默认是REQUEST
  servlet-name---拦截那个Servlet 给名字就好了

配置说明

过虑器的配置:以下几乎是所有单位的标准配置

  autoLoginFilter
  cn.itcast.autologinfilter.AutoLoginFilter


  autoLoginFilter
  /*

filter-name是过虑器的名称
filter-class是过虑器的类文件
init-param是过虑器的初始化参数。
param-name – 是参数名。
param-value - 是参数值。
filter-mapping是过虑器的映射信息。
url-pattern-是需要过虑的资源url.

全站压缩实例

过滤器代码

package cn.hncu.filters;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
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.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
/*
 * 全战压缩~  思路:去之前把response加强了(带个容器),回来的时候把容器内的东西压缩了 再用原来response的输出去
 */
public class GzipFilter implements Filter{

    @Override
    public void init(FilterConfig paramFilterConfig) throws ServletException {
        // TODO Auto-generated method stub

    }

    @Override
    public void doFilter(ServletRequest paramServletRequest,
            ServletResponse paramServletResponse, FilterChain paramFilterChain)
            throws IOException, ServletException {
        HttpServletResponse resp = (HttpServletResponse) paramServletResponse;
        MyResponse respone = new MyResponse(resp);
        //用我们写的带容器的Myrespone 替换原来的 
        paramFilterChain.doFilter(paramServletRequest, respone);

        //执行完了后,拿到源数据~
        byte[] src_data =respone.getBout().toByteArray(); 

        //测试一下源数据长度
        System.out.println(src_data.length);

        //通过gizp对源数据压缩
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        GZIPOutputStream gzip = new GZIPOutputStream(bout);
        gzip.write(src_data);
        gzip.close();// 关流很重要不然会没数据啊~
        byte[] gzip_data = bout.toByteArray();

        //测试一下压缩后的数据长度
        System.out.println(gzip_data.length);

        //压缩完以后,再通过原来的response发送出去
        resp.setHeader("Content-Encoding", "gzip");
        resp.getOutputStream().write(gzip_data);
    }

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

}
class MyResponse extends HttpServletResponseWrapper{
    private ByteArrayOutputStream bout = new ByteArrayOutputStream();
    private PrintWriter writer = null;
    public MyResponse(HttpServletResponse response) {
        super(response);
    }
    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        return new MyOutputStream(bout);
    }
    @Override
    public PrintWriter getWriter() throws IOException {

        writer= new PrintWriter(new OutputStreamWriter(bout, "utf-8"),true);
        return writer;
    }
    public ByteArrayOutputStream getBout(){
        if(writer!=null){ // 这一句很重要,没有这个关流会导致网页很多数据在缓存内,网页无法显示
            writer.close();
        }
        return bout;
    }
}
class MyOutputStream extends ServletOutputStream{
    private ByteArrayOutputStream bout = null;
    public MyOutputStream(ByteArrayOutputStream bout){
        this.bout = bout;
    }
    @Override
    public void write(int b) throws IOException {
        bout.write(b); //把数据读到容器中区
    }

}

web.xml



   


    
    GzipFilter
    cn.hncu.filters.GzipFilter
   
  
    GzipFilter
    /*
  
  
    LoginServlet
    cn.hncu.servlet.LoginServlet
  
  
    WordServlet
    cn.hncu.servlet.WordServlet
  
  
    Gzip_Servlet
    cn.hncu.servlet.Gzip_Servlet
  
  
    LoginServlet
    /LoginServlet
  
  
    WordServlet
    /WordServlet
  
  
    Gzip_Servlet
    /Gzip_Servlet
  
  
    index.jsp
  

说明一下:因为真个网址会有两种流,字节流和字符流,我们要做到全站压缩就得兼容两种。其中有一些细节我已经写在代码注释里了

作者:网络 来源:weixin_377