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的先后顺序一致!

  • 相关阅读:
    有效管理时间的十八种方法
    针对某个块下面的按钮注册点击事件
    vs2015运行项目时出现“编译器失败,错误代码为 1”的解决方案
    淘宝API调用 申请 获取session key
    中小型研发团队架构实践:生产环境诊断利器WinDbg帮你快速分析异常情况Dump文件
    中小型研发团队架构实践:如何规范公司所有应用分层?
    中小型研发团队架构实践:电商如何做企业总体架构?
    中小型研发团队架构实践:高效率、低风险,一键发布并测试的持续集成工具Jenkins
    ASP.NET全栈开发验证模块之在Vue中使用前端校验
    计算机基础存储结构
  • 原文地址:https://www.cnblogs.com/qrlozte/p/3178651.html
Copyright © 2011-2022 走看看