A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

        在JavaWeb阶段,大家都学习了Filter这样一个Web组件,知道了过滤器Filter就是用于过滤请求,对请求或响应添加处理逻辑的。今天我们来对Filter的运行流程做一个详细介绍。看一看Filter到底是怎么一步步执行的。
        首先我们说一下Filter的编写流程。
                第一步:写一个类实现Filter接口。
                第二步:实现Filter接口中的所有方法,过滤的逻辑在doFilter方法中编写。可以选择使用filterChain.doFilter()方法放行请求。
                第三步:在web.xml中配置Filter,或者使用注解配置Filter。
        我们在这主要关注一下filterChain.doFilter()这个方法。如下图:
                           
        这个方法我们一般称之为放行,也就是不在过滤器中拦截请求。反之,如果没有放行操作,请求将不再到达目标资源,而是直接终止。那么,“放行”到底把请求放行到哪去了呢,之后又是怎么执行的呢,我们一起来分析一下。
        要想知道放行之后干嘛了,就得知道FilterChain这个类的作用。FilterChain是过滤器链的意思,当一个请求访问服务器上的一个项目时,如果该请求的url和过滤器的urlpattern的规则一致,则所有符合规则的Filter将串起来,组成一个过滤器链。Filter在过滤器链中的顺序和配置相关。如果是web.xml中配置的,则和filter-mapping节点的先后顺序一致;如果是注解配置的,那么Filter的先后顺序和Filter类的类名字符串比较结果顺序一致。
        举个例子:
                有Filter1,Filter2两个Filter,都用注解配置url-pattern为“/*”,那么如果来了一个请求想要请求项目中的一个Serlvet,则两个过滤器会组成一个过滤器链,Filter1在前,Filter2在后。我用画图的形式描述了这一流程,图中的代码均为伪代码。如下:
                  
                请求首先被Filter1过滤,执行Filter1的doFilter方法,然后打印出“Filter1”执行了
                然后Filter1的chain.doFilter方法执行,这里我们解释下该方法内部做了什么事情。
                       chain也就是过滤器链,调用doFilter方法时查找过滤器链中是否有下一个过滤器节点,如果有,则调用下一个过滤器的doFilter方法(这也就是为什么chain的方法也叫doFilter的原因了)。如果没有下一个过滤器,则把请求放行到目标资源(也就是请求原本要请求到的位置,也就是案例中的Servlet)。
                那么在Filter1种,有下一个过滤器Filter2,所以此时沿着箭头1执行到Filter2的doFilter方法中。打印“Filter2执行了”。
                继续判断,Filter2的chain.doFilter()得知没有下一个过滤器节点,所以直接放行到Servlet中,沿着箭头2执行Servlet的service方法,打印“Servlet执行了”。
                Servlet的service方法执行完毕后,沿着箭头3回到Filter2中的chain.doFilter(),而chain.doFilter()执行完毕后,打印“Filter2结束了”。
                Filter2的doFilter方法执行完毕后,沿着箭头4回到Filter1中的chain.doFilter(),而chain.doFilter()执行完毕后,打印“Filter1结束了”。
                至此,整个过滤器链执行完毕,响应回到客户端。
        以上就是对Filter的执行流程的解析了,在这个过程中,如果有任何一个过滤器节点没有放行请求,代码都会终止不会继续执行,所以请求也就到达不了目标资源,导致Servlet不能被访问。
        其实,Filter使用的就是一个非常典型的设计模式,责任链的设计模式。这种设计模式把一个任务分解为若干个链条的节点,每个节点独立执行逻辑,优点就是节点可以任意添加和删除,便于解耦。而缺点同样明显,链式结构想要遍历就必须从链头开始执行到最后,不能从中间开始执行,或者只执行某个指定的节点。
        对于过滤器Filter,你是不是又多了解了一些呢?

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马