tomcat原理及实现-----tomcat的过滤器(第三篇)

来源:互联网 发布:淘宝怎么留言卖家 编辑:程序博客网 时间:2024/06/05 08:49

对于tomcat的过滤器,大家应该都不陌生,每当一个http请求到达的时候,都会经过过滤器,我们知道过滤器会优先于servlet执行,而我们使用的时候只是在web.xml文件中配置了一个filter标签,那他到底在tomcat中是个什么东西呢。今天不妨就来了解一下

最后附上源码,供大家参考:

(1)bootstrap类的启动设置:

<span style="white-space:pre"></span>HttpConnector connector = new HttpConnector();<span style="background-color: rgb(102, 255, 255);">Wrapper wrapper = new SimpleWrapper();</span>wrapper.setServletClass("ModernServlet");Loader loader = new SimpleLoader();Valve valve1 = new HeaderLoggerValve();   ---这就相当于一个过滤器Valve valve2 = new ClientIPLoggerValve();wrapper.setLoader(loader);((Pipeline) wrapper).addValve(valve1);((Pipeline) wrapper).addValve(valve2);connector.setContainer(wrapper);
(2)addValue()方法,最后是将value添加在了Value的对象数组里。具体的代码参考如下

这是在bootstrap中的SimpleWrapper 中的,见下:

<span style="white-space:pre"></span>public synchronized void addValve(Valve valve) {pipeline.addValve(valve);<span style="white-space:pre"></span>}
是通过调用pipeline的addValue()方法实现的添加。接下来我们在仔细看看pipline这个类SimplePipeline:

import java.io.IOException;import javax.servlet.ServletException;import org.apache.catalina.Contained;import org.apache.catalina.Container;import org.apache.catalina.Pipeline;import org.apache.catalina.Request;import org.apache.catalina.Response;import org.apache.catalina.Valve;import org.apache.catalina.ValveContext;public class SimplePipeline implements Pipeline {public SimplePipeline(Container container) {setContainer(container);}// The basic Valve (if any) associated with this Pipeline.protected Valve basic = null;// The Container with which this Pipeline is associated.protected Container container = null;// the array of Valvesprotected Valve valves[] = new Valve[0];public void setContainer(Container container) {this.container = container;}public Valve getBasic() {return basic;}public void setBasic(Valve valve) {this.basic = valve;((Contained) valve).setContainer(container);}public void addValve(Valve valve) {if (valve instanceof Contained)((Contained) valve).setContainer(this.container);synchronized (valves) {Valve results[] = new Valve[valves.length + 1];System.arraycopy(valves, 0, results, 0, valves.length);results[valves.length] = valve;valves = results;}}public Valve[] getValves() {return valves;}public void invoke(Request request, Response response) throws IOException,ServletException {// Invoke the first Valve in this pipeline for this request(new SimplePipelineValveContext()).invokeNext(request, response);}public void removeValve(Valve valve) {}// this class is copied from org.apache.catalina.core.StandardPipeline// class's// StandardPipelineValveContext inner class.protected class SimplePipelineValveContext implements ValveContext {protected int stage = 0;public String getInfo() {return null;}public void invokeNext(Request request, Response response)throws IOException, ServletException {int subscript = stage;stage = stage + 1;// Invoke the requested Valve for the current request threadif (subscript < valves.length) {valves[subscript].invoke(request, response, this);} else if ((subscript == valves.length) && (basic != null)) {basic.invoke(request, response, this);} else {throw new ServletException("No valve");}}} // end of inner class}
过滤的链就是在这个类中形成的哦

在SimplePipeline中,addValue()方法是将前面提到的filter添加到了Value的对象数组中,在其内部类中SimplepipelineContext中,invokeNext()则实现了过滤链的迭代调用,当然了,这个迭代调用是从创建HttpProcessor中开始的: connector.getContainer().invoke(request, response);

因为在bootstrap中已经设置了connector.setContainer(wrapper); 所以在就是调用的SimpleWrapper中的invoke()方法:

注意:过滤链可以实现对数据的有序修改----》》》这次的request和response对象都会传入到下一个invoke方法中,但是如果某个过滤器发生异常,那么过滤链就无法完成,最后到各什么err页面什么的。struts2的什么拦截器也是这么个事,在struts中他通过一个/×的过滤器,拦截所有请求,然后自由发挥对数据进行处理

public void invoke(Request request, Response response) throws IOException,ServletException {pipeline.invoke(request, response);}
在pipline中还是调用的:

public void invoke(Request request, Response response) throws IOException,
ServletException {
// Invoke the first Valve in this pipeline for this request
(new SimplePipelineValveContext()).invokeNext(request, response);
}
因为在SimplePipeline中已经存在了所有过滤链的过滤器(value数组),所以在invokeNext中,是通过游标的方式来实现一次调用的。

连接:http://download.csdn.net/detail/hao707822882/7484611  免费下载


在有个过滤器,那我们是不是应该想想容器的生命周期啦。。。。

0 0
原创粉丝点击