乐鱼电竞

    教育行业A股IPO第一股(股票代码 003032)

    全国咨询/投诉热线:400-618-4000

    filter过滤链:Filter链是如何构建的?

    更新时间:2020年09月18日14时56分 来源:乐鱼播客 浏览次数:

    在一个Web应用程序中可以注册多个Filter程序,每个Filter程序都可以针对某一个URL进行拦截。如果多个Filter程序都对同一个URL进行拦截,那么这些Filter就会组成一个Filter链(也叫过滤器链)。Filter链用FilterChain对象来表示,FilterChain对象中有一个doFilter()方法,该方法作用就是让Filter链上的当前过滤器放行,请求进入下一个Filter,接下来通过一个图例来描述Filter链的拦截过程,如图1所示。

    filter链

    图1 Filter链

    在图1中,当浏览器访问Web服务器中的资源时需要经过两个过滤器Filter1和Filter2,首先Filter1会对这个请求进行拦截,在Filter1过滤器中处理好请求后,通过调用Filter1的doFilter()方法将请求传递给Filter2,Filter2将用户请求处理后同样调用doFilter()方法,最终将请求发送给目标资源。当Web服务器对这个请求做出响应时,也会被过滤器拦截,这个拦截顺序与之前相反,最终将响应结果发送给客户端。

    为了让读者更好的学习Filter链,接下来,通过一个案例,分步骤演示如何使用Filter链拦截MyServlet的同一个请求,具体如下:

    (1)在chapter04工程的cn.itcast.chapter04.filter包中新建MyFilter01和MyFilter02,如例1和2所示。

    例1 MyFilter01.java

     1  package cn.itcast.chapter04.filter;
    
     2  import java.io.*;
    
     3  import javax.servlet.*;
    
     4  public class MyFilter01 implements Filter {
    
     5    public void destroy() {
    
     6      // 过滤器对象在销毁时自动调用,释放资源
    
     7    }
    
     8    public void doFilter(ServletRequest request, ServletResponse response,
    
     9        FilterChain chain) throws IOException, ServletException {
    
     10     // 用于拦截用户的请求,如果和当前过滤器的拦截路径匹配,该方法会被调用
    
     11     PrintWriter out=response.getWriter();
    
     12     out.write("Hello MyFilter01</br>");
    
     13     chain.doFilter(request, response);
    
     14   }
    
     15   public void init(FilterConfig fConfig) throws ServletException {
    
     16     // 过滤器对象在初始化时调用,可以配置一些初始化参数
    
     17   }
    
     18 }

    例2 MyFilter02.java

    1  package cn.itcast.chapter04.filter;
    
     2  import java.io.*;
    
     3  import javax.servlet.Filter;
    
     4  import javax.servlet.*;
    
     5  public class MyFilter02 implements Filter {
    
     6    public void destroy() {
    
     7      // 过滤器对象在销毁时自动调用,释放资源
    
     8    }
    
     9    public void doFilter(ServletRequest request, ServletResponse response,
    
     10       FilterChain chain) throws IOException, ServletException {
    
     11     // 用于拦截用户的请求,如果和当前过滤器的拦截路径匹配,该方法会被调用
    
     12     PrintWriter out=response.getWriter();
    
     13     out.write("MyFilter02 Before</br>");
    
     14     chain.doFilter(request, response);
    
     15     out.write("</br>MyFilter02 After</br>");  
    
     16   }
    
     17   public void init(FilterConfig fConfig) throws ServletException {
    
     18     // 过滤器对象在初始化时调用,可以配置一些初始化参数
    
     19   }
    
     20 }

    (2)在web.xml文件中将MyFilter01和MyFilter02注册在MyServlet前面,具体如下所示:

    <filter>
    
      <filter-name>MyFilter01</filter-name>
    
      <filter-class>cn.itcast.chapter04.filter.MyFilter01</filter-class>
    
     </filter>
    
     <filter-mapping>
    
      <filter-name>MyFilter01</filter-name>
    
      <url-pattern>/MyServlet</url-pattern>
    
     </filter-mapping>
    
     <filter>
    
      <filter-name>MyFilter02</filter-name>
    
      <filter-class>cn.itcast.chapter04.filter.MyFilter02</filter-class>
    
     </filter>
    
     <filter-mapping>
    
      <filter-name>MyFilter02</filter-name>
    
      <url-pattern>/MyServlet</url-pattern>
    
     </filter-mapping>
    
     <servlet>
    
       <servlet-name>MyServlet</servlet-name>
    
      <servlet-class>cn.itcast.chapter04.filter.MyServlet</servlet-class>
    
     </servlet>
    
     <servlet-mapping>
    
      <servlet-name>MyServlet</servlet-name>
    
      <url-pattern>/MyServlet</url-pattern>
    
     </servlet-mapping>

    (3)重新启动Tomcat服务器,在浏览器地址栏中输入http://localhost:8080/chapter04/MyServlet,此时,浏览器窗口中的显示结果如图2所示。

    运行结果

    从图2中可以看出,MyServlet首先被MyFilter01拦截了,打印出MyFilter01中的内容,然后被MyFilter02拦截,直到 MyServlet被MyFilter02放行后,浏览器才显示出MySerlvet中的输出内容。

    需要注意的是,Filter链中各个Filter的拦截顺序与它们在web.xml文件中元素的映射顺序一致,由于MyFilter01的元素位于MyFilter02的元素前面,因此用户的访问请求首先会被MyFilter01拦截,然后再被MyFilter02拦截。


    猜你喜欢:
    什么是filter?filter是用来做什么的?

    filter映射:filter的两种映射方式

    java高级软件工程师

    0 分享到:
    和我们在线交谈!
    【网站地图】【sitemap】