Filter过滤器机制
2017-01-18 18:02
155 查看
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方法,依此类推,直至所有过滤器都执行完毕。
public interface Filter {
.....
//执行过滤
public void doFilter ( ServletRequest request, ServletResponse response, throws IOException, ServletException;
}
public interface FilterChain {
public void doFilter ( ServletRequest request, ServletResponse response ) throws IOException, ServletException;
}
FilterConfig接口检索过滤器名、初始化参数以及活动的Servlet上下文。ApplicationFilterConfig是其实现类
ApplicationFilterChain在catalina.jar的org.apache.catalina.core包中
class ApplicationFilterChain implements FilterChain {
..................
private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0];
private int pos = 0;
private int n = 0;
//pos为当前filter的所在位置,n为filters数组的长度
if (pos < n) {
//pos++执行后,把filterchain的当前filter指向下一个
ApplicationFilterConfig filterConfig = filters[pos++];
Filter filter = null;
try {
filter = filterConfig.getFilter();
//filter执行过滤操作
filter.doFilter(request, response, this);
}
...
}
}
实例如下:
class SampleFilter implements Filter {
........
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain)
throws IOException, ServletException {
//do something
.....
//request, response传递给下一个过滤器进行过滤
chain.doFilter(request, response);
}
}
先描述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中的主要代码如下:
ApplicationFilterChain filterChain =
createFilterChain(request, servlet);
/*略
String jspFile = wrapper.getJspFile();
if (jspFile != null)
sreq.setAttribute(Globals.JSP_FILE_ATTR, jspFile);
else
sreq.removeAttribute(Globals.JSP_FILE_ATTR);
if ((servlet != null) && (filterChain != null)) {
filterChain.doFilter(sreq, sres);
}
sreq.removeAttribute(Globals.JSP_FILE_ATTR);
在StandardWrapperValve的invoke中(也就是上面贴的代码),第10行的代码就是调用servlet的入口,传说中的doFilter()。
Tomcat的过滤器主要由Filter、FilterChain组成,FilterChain包含一个Filter数组.当Wrapper执行FilterChain的doFilter(request,response)方法时,FilterChain首先调用第一个Filter的doFilter(request,response,filterchain)方法,当第一个filter做完过滤操作后,它又会调用filterchain的doFilter方法,此时filterchain的当前filter已变为第二个filter,第二个filter又执行dofilter方法,依此类推,直至所有过滤器都执行完毕。
public interface Filter {
.....
//执行过滤
public void doFilter ( ServletRequest request, ServletResponse response, throws IOException, ServletException;
}
public interface FilterChain {
public void doFilter ( ServletRequest request, ServletResponse response ) throws IOException, ServletException;
}
FilterConfig接口检索过滤器名、初始化参数以及活动的Servlet上下文。ApplicationFilterConfig是其实现类
ApplicationFilterChain在catalina.jar的org.apache.catalina.core包中
class ApplicationFilterChain implements FilterChain {
..................
private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0];
private int pos = 0;
private int n = 0;
//pos为当前filter的所在位置,n为filters数组的长度
if (pos < n) {
//pos++执行后,把filterchain的当前filter指向下一个
ApplicationFilterConfig filterConfig = filters[pos++];
Filter filter = null;
try {
filter = filterConfig.getFilter();
//filter执行过滤操作
filter.doFilter(request, response, this);
}
...
}
}
实例如下:
class SampleFilter implements Filter {
........
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain)
throws IOException, ServletException {
//do something
.....
//request, response传递给下一个过滤器进行过滤
chain.doFilter(request, response);
}
}
先描述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中的主要代码如下:
ApplicationFilterChain filterChain =
createFilterChain(request, servlet);
/*略
String jspFile = wrapper.getJspFile();
if (jspFile != null)
sreq.setAttribute(Globals.JSP_FILE_ATTR, jspFile);
else
sreq.removeAttribute(Globals.JSP_FILE_ATTR);
if ((servlet != null) && (filterChain != null)) {
filterChain.doFilter(sreq, sres);
}
sreq.removeAttribute(Globals.JSP_FILE_ATTR);
在StandardWrapperValve的invoke中(也就是上面贴的代码),第10行的代码就是调用servlet的入口,传说中的doFilter()。
相关文章推荐
- iOS学习笔记-032.数据的读取——plist写入
- bootstrap——组件(一、下拉菜单)
- warning: dereferencing pointer ** does break strict-aliasing rules
- meta标签中的http-equiv属性使用介绍
- ambari2.4.2在CentOS7上的二次开发
- iOS -计算时间差
- OS_Init
- zabbix添加防火墙流量监控
- asp.net mvc各版本特性一览
- Grumpy: Go 运行 Python
- 利用类的成员函数重载双目运算符其最多只有一个参数
- socket API通俗理解
- LeetCode 453. Minimum Moves to Equal Array Elements
- 正则表达式
- linux升级内核,出现:mount:could not find filesystem‘/dev/root’的解决方法
- A. Jumping Ball
- iOS学习笔记-031.数据的读取——沙盒模型
- dfs序
- uCOS-III阅读,第一天,也就瞎看看
- canvas做的桌面