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

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

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

(1)bootstrap类的启动设置:

HttpConnector connector = new HttpConnector();

Wrapper wrapper = new SimpleWrapper();

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 中的,见下:

public synchronized void addValve(Valve valve) {

pipeline.addValve(valve);

}

是通过调用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 Valves

protected 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 thread

if (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中,是通过游标的方式来实现一次调用的。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值