tomcat内部过滤器采用了责任链的设计模式,

Tomcat的过滤器主要由Filter、FilterChain组成,FilterChain包含一个Filter数组.当Wrapper执行FilterChain的doFilter(request,response)方法时,FilterChain首先调用第一个Filter的doFilter(request,response,filterchain)方法,当第一个filter做完过滤操作后,它又会调用filterchain的doFilter方法,此时filterchain的当前filter已变为第二个filter,第二个filter又执行dofilter方法,依此类推,直至所有过滤器都执行完毕。

  1. public interface Filter {
  2. .....
  3. //执行过滤
  4. public void doFilter ( ServletRequest request, ServletResponse response, throws IOException, ServletException;
  5. }
  6. public interface FilterChain {
  7. public void doFilter ( ServletRequest request, ServletResponse response ) throws IOException, ServletException;
  8. }

FilterConfig接口检索过滤器名、初始化参数以及活动的Servlet上下文。ApplicationFilterConfig是其实现类

ApplicationFilterChain在catalina.jar的org.apache.catalina.core包中

  1. class ApplicationFilterChain implements FilterChain {
  2. ..................
  3. private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0];
  4. private int pos = 0;
      private int n = 0;
  5. //pos为当前filter的所在位置,n为filters数组的长度
  6. if (pos < n) {
  7. //pos++执行后,把filterchain的当前filter指向下一个
  8. ApplicationFilterConfig filterConfig = filters[pos++];
  9. Filter filter = null;
  10. try {
  11. filter = filterConfig.getFilter();
  12. //filter执行过滤操作
  13. filter.doFilter(request, response, this);
  14. }
  15. ...
  16. }
  17. }
  18. 实例如下:

  19. class SampleFilter implements Filter {
  20. ........
  21. public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain)
  22. throws IOException, ServletException {
  23. //do something
  24. .....
  25. //request, response传递给下一个过滤器进行过滤
  26. chain.doFilter(request, response);
  27. }
  28. }

先描述tomcat的方法调用序列。

      具体过程如下:
                (1)connector 创建 request 和 response 对象;
                (2)connector 调用 StandardContext 实例的 invoke 方法;
                (3)StandardContext 接着调用其 pipeline 的 invoke 方法,StandardContext 中 pipeline 的 basic valve 是
  StandardContextValve,因此,StandardContext 的 pipeline 会调用 StandardContextValve 的 invoke 方法;
                (4)StandardContextValve 的 invoke 方法获取 wrapper 处理请求,调用 wrapper 的 invoke 方法;
                (5)StandardWrapper 是 Wrapper 接口的标准实现,StandardWrapper 实例的 invoke 方法会调用其
  pipeline 的 invoke 方法;
                (6)StandardWrapper 的 pipeline 中的 basic valve 是 StandardWrapperValve,因此,会调用其 invoke 方
 法,StandardWrapperValve 调用 wrapper 的 allocate 方法获取 servlet 实例;
                (7)allocate 方法调用 load 方法载入 servlet 类,若已经载入,则无需重复载入;
                (8)load 方法调用 servlet 的 init 方法;
                (9)StandardWrapperValve 调用 servlet 的 service 方法。

StandardWrapperValve中的主要代码如下:

  1. ApplicationFilterChain filterChain =
  2. createFilterChain(request, servlet);
  3. /*略
  4. String jspFile = wrapper.getJspFile();
  5. if (jspFile != null)
  6. sreq.setAttribute(Globals.JSP_FILE_ATTR, jspFile);
  7. else
  8. sreq.removeAttribute(Globals.JSP_FILE_ATTR);
  9. if ((servlet != null) && (filterChain != null)) {
  10. filterChain.doFilter(sreq, sres);
  11. }
  12. sreq.removeAttribute(Globals.JSP_FILE_ATTR);

在StandardWrapperValve的invoke中(也就是上面贴的代码),第10行的代码就是调用servlet的入口,传说中的doFilter()。

最新文章

  1. ERP软件的价格设计
  2. 转:python webdriver API 之操作测试对象
  3. Socket(TCP)客户端请求和服务端监听和链接基础(附例子)
  4. atitit.设计模式(2) -----查询方式/ command 总结
  5. [原创].NET 分布式架构开发实战五 Framework改进篇
  6. shell 创建带参数的命令方法
  7. Shell第三篇:基本语法
  8. 201521123045java课程设计---定时器
  9. mysql 打开慢查询日志
  10. 如何在WDM中使用xp系统的DMA用来处理数据
  11. js页面路径拼接字符串进行参数传递
  12. Entity Framework Core一键生成实体命令
  13. 如何通过Openssl实现私有CA,并为HTTP服务提供TLS/SLL安全机制
  14. 网络对抗技术 2017-2018-2 20152515 Exp7 信息搜集与漏洞扫描
  15. linux下生成https的crt和key证书
  16. C/C++ -- Gui编程 -- Qt库的使用 -- Qt5试用
  17. C /C ++中结构体的定义
  18. django查询集-17
  19. myeclipse10中对象无法点出下面的方法和属性
  20. js项目

热门文章

  1. D. Vasya And The Matrix(Educational Codeforces Round 48)
  2. 全面学习ORACLE Scheduler特性(9)创建Chains
  3. ES6 学习笔记 - let和const
  4. Python数据科学安装Numby,pandas,scipy,matpotlib等(IPython安装pandas)
  5. Android基础TOP4_2:弹窗式选择列表
  6. 7z.exe 命令行压缩文件排除文件(exclude filenames) 手记
  7. MFC_2.10选项卡控件的封装
  8. SDK_进度条和滑块
  9. JMeter在linux上分布式压测遇到的坑(三)
  10. vue组件---动态组件之多标签页面