zoukankan      html  css  js  c++  java
  • Filter的执行顺序

    Filter有如下几个用处。

    • 在HttpServletRequest到达Servlet之前,拦截客户的HttpServletRequest
    • 根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据。
    • 在HttpServletResponse到达客户端之前,拦截HttpServletResponse
    • 根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。

    首先,要知道在web.xml中,<url-pattern>指定了filter要进行拦截url范围,<url-pattern>/*</url-pattern>则表示拦截你%web-root%下对所有url的request和response

    其次,Filter.doFilter()之中的代码,按执行顺序分成了3部分,1、在chain.doFilter()执行之前的代码,是用于处理request对象的,2、chain.doFilter(),3、chain.doFilter()之后的代码是用来处理response对象的

    这里我们做2个filter,如下

    FirstFilter

    package org.lxh.filterdemo;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    public class FirstFilter implements Filter { 
        @Override  
        public void destroy() {   
    
        }   
    
        @Override  
        public void doFilter(ServletRequest request, ServletResponse response,   
                FilterChain chain) throws IOException, ServletException {   
            System.out.println("before invoke firstFilter's chain.doFilter() ..");   
            chain.doFilter(request, response);   
            System.out.println("after invoke firstFilter's chain.doFilter() ..");   
        }
    
        @Override  
        public void init(FilterConfig arg0) throws ServletException {   
            System.out.println("firstFilter init()..."); 
        }
    }

    SecondFilter

    package org.lxh.filterdemo;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    public class SecondFilter implements Filter { 
        @Override  
        public void destroy() {   
    
        }   
    
        @Override  
        public void doFilter(ServletRequest request, ServletResponse response,   
                FilterChain chain) throws IOException, ServletException {   
            System.out.println("before invoke secondFilter's chain.doFilter() ..");   
            chain.doFilter(request, response);   
            System.out.println("after invoke secondFilter's chain.doFilter() ..");   
        }
    
        @Override  
        public void init(FilterConfig arg0) throws ServletException {   
            System.out.println("secondFilter init()..."); 
        }
    }

    web.xml,注意2个filter-mapping的先后顺序是:first在前,second在后

    <!-- first & second filter -->
        <filter>   
            <filter-name>firstFilter</filter-name>   
            <filter-class>org.lxh.filterdemo.FirstFilter</filter-class>   
        </filter>   
        <filter-mapping>   
            <filter-name>firstFilter</filter-name>   
            <url-pattern>/*</url-pattern>   
        </filter-mapping>
        <filter>   
            <filter-name>secondFilter</filter-name>   
            <filter-class>org.lxh.filterdemo.SecondFilter</filter-class>   
        </filter>
        <filter-mapping>   
            <filter-name>secondFilter</filter-name>   
            <url-pattern>/*</url-pattern>   
        </filter-mapping>

    访问http://127.0.0.1:8080/mldn/,运行结果如下

    before invoke firstFilter's chain.doFilter() ..
    before invoke secondFilter's chain.doFilter() ..
    after invoke secondFilter's chain.doFilter() ..
    after invoke firstFilter's chain.doFilter() ..

    上面的运行结果说明,执行流程是这样的:

    ... 客户端请求...  

           进入firstFilter.doFilter() 

                      System.out.println("before invoke firstFilter's chain.doFilter() ..")

                      chain.doFilter(request, response)

                进入secondFilter.doFilter()

                           System.out.println("before invoke secondFilter's chain.doFilter() ..")

                           chain.doFilter(request, response)

                       执行处理页面的servlet代码

                                              .. servlet代码执行完毕...返回

                           System.out.println("after invoke secondFilter's chain.doFilter() ..")

                             执行完毕,返回

          System.out.println("after invoke secondFilter's chain.doFilter() ..")

          执行完毕,返回

    客户端接收响应

    用图来表示的话,就可以用下面的图来表示,可见,中间两个大框从左到右就依次表示的是first.doFilter和second.doFilter,code1和code2分别表示chain.doFilter之前的print和chain.doFilter之后的print

    好的,现在把web.xml改为如下,但是这次,注意,2个filter-mapping的先后顺序是:second在前,first在后

        <filter>   
            <filter-name>secondFilter</filter-name>   
            <filter-class>org.lxh.filterdemo.SecondFilter</filter-class>   
        </filter>
        <filter-mapping>   
            <filter-name>secondFilter</filter-name>   
            <url-pattern>/*</url-pattern>   
        </filter-mapping>
        <filter>   
            <filter-name>firstFilter</filter-name>   
            <filter-class>org.lxh.filterdemo.FirstFilter</filter-class>   
        </filter>   
        <filter-mapping>   
            <filter-name>firstFilter</filter-name>   
            <url-pattern>/*</url-pattern>   
        </filter-mapping>

    执行结果如下:

    before invoke secondFilter's chain.doFilter() ..

    before invoke firstFilter's chain.doFilter() ..

    after invoke firstFilter's chain.doFilter() ..

    after invoke secondFilter's chain.doFilter() ..

    显然,这次是secondFilter.doFilter()先执行,所以,多个filter.doFilter()的执行先后顺序与web.xml中对应的filter-mapping的先后顺序一致!

  • 相关阅读:
    常见http状态码
    通过adb shell命令查看内存,CPU,启动时间,电量等信息
    Jmeter获取数据库数据参数化
    jmeter链接mysql数据库,sql数据库,oracle数据库
    appium 隐藏键盘
    python编码
    python:打印所有文件名字的扩展名
    python中字符串常见操作
    python中的字符串存储及切片介绍
    Ubuntu14.04安装部署bugzilla5.0.3
  • 原文地址:https://www.cnblogs.com/qrlozte/p/3178651.html
Copyright © 2011-2022 走看看