tomcat解析(十九)对客户请求的处理3

下面是StandardContextValve的invoke方法内容
    <1>对于路径中直接访问META-INF或WEB-INF目录下资源的,直接返回404错误
     

    <2>如果此时当前Context正在reload,则线程暂停并设置最新的ClassLoader;如果匹配到的wrapper处理不存在,则返回404错误,若wrapper处于不可用的状态,重新获取,因为可以处理reload的过程中
      

    <3>触发该Context下已注册的ServletContextAttributeListener,ServletRequestAttributeListener,ServletRequestListener及HttpSessionAttributeListener的contextInitialized事件,在第四步后还触发其requestDestroyed事件,这里没有注册这几个监听器,暂时不讲.
    <4>调用对应wrapper的方法:wrapper.getPipeline().getFirst().invoke(request, response);
依然可以根据StandardWrapper的构造方法看到将调用的是StandardWrapperValve的invoke方法
内容大概有
1.查看当前context及wrapper对象是否处理于unavailable状态,主要是服务器关闭或重启问题
2.状态可用,分配实例化及初始化当前Wrapper对应的Servlet对象,servlet = wrapper.allocate()
3.以当前请求,servlet及wrapper对象为参数创建对应的ApplicationFilterChain对象(实现了FilterChain接口:Filter将使用到),此时会将当前Context里与该request对应的Filter加到ApplicationFilterChain里,无特殊顺序,因此将是按照web.xml里的声明顺序来的
4.调用ApplicationFilterChain对象的doFilterEvent或doFilter方法(两者如何区别仍未知,后续再说),java Web开发很多都在此部分内容;doFilter方法里主要又是调用了internalDoFilter方法进行处理
3.对实例化的Servlet及ApplicationFilterChain对象进行资源回收

ApplicationFilterChain.internalDoFilter内容大概如下:
1.调用所持有的第一个Filter的doFilter方法,以request,response及自身为参数
    

设想开发者编写了两个Filter,在过滤请求的时候便会执行上面这一段代码来调用第一个Filter,如果在第一个Filter里又调用了FilterChain.doFilter,则又会调用上面这一段代码,而此时pos已自加1,因此将会调用第二个Filter处理类,依次类推直到最后的Filter的doFilter方法执行完,之后便会返回前一个Filter继续运行其调用FilterChain.doFilter之后的代码,又依次类推直到第一个Filter.当然这部分是Filter的执行,我们都知道还有一个Servlet会执行,那到底Servlet是什么时候执行呢?依然是ApplicationFilterChain.internalDoFilter,当所有的Filter都已执行,并且在最后一个Filter又调用了FilterChain.doFilter,再来到这个方法时则不会再执行上面列出的代码,而是运行下面这段代码:
  

可以看到在最后的Filter再执行FilterChain.doFilter的时候将会执行请求对应的Servlet类的service方法,这也是我们早已知道的一个事实,现在只是揭开了其实现的面纱.当然既然还有Servlet需要执行,那上面的一段话应该是这样描述才对,依次类推直到Servlet执行完成后又返回其前面的Filter,再依次类推直到第一个Filter.这个实现其实与之后我们看过的PipeLine方式实现上异曲同工,但个人认为相对于Pipeline的实现,Filter的开发键较偏面向过程,而Pipeline的实现较OO(if u know what i mean:),如之前所说,在Struts2的拦截器上也是相似的模式,但也是OO模式的,所以我在猜想编写Filter实现的开发人员可能拥有较长时间的面向过程编程资历,所以一下子比较难转换过来(纯属个人看法:)
另有一点需要注意的,客户端的返回是什么时候给的呢?如果我们不用JSP写界面,直接用Servlet或许比较明显地看出,我们一般都会写
 PrintWriter out = Response.getWriter();
 out.print();
 out.close();
这里即会打开一个客户请求的返回结果流,然后将结果写入,因此即使我们有Filter可对返回结果进行处理,但事实在Servlet返回之后的处理是不会表现到客户端的.在实际的MVC框架如STRUTS2,SPRING MVC中,使用了JSP做为输出,但情况也是如此的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值