容器
A container is a module that processes the requests for a servlet and populates the response objects for web clients
容器是一个处理servlet请求,并为web客户端提供响应的模块。
org.apache.catalina.Container 接口定义了容器的形式,有四种容器:Engine (引擎), Host(主机), Context(上下文), 和 Wrapper(包装器)。
容器接口
一个容器必须实现 org.apache.catalina.Container接口。就如在第四章中看到的,传递一个Container实例给Connector对象的setContainer 方法,然后Connector对象就可以使用container的invoke方法
-
Engine. 表示整个Catalina的servlet引擎
-
Host. 表示一个拥有数个上下文的虚拟主机
-
Context. 表示一个Web应用,一个 context包括一个或多个wrapper
-
Wrapper. 表示一个独立的servlet
一个容器可以有一个或多个低层次上的子容器。例如,一个Context有一个或多个wrapper,而wrapper 作为容器层次中的最底层,不能包含子容器。
Pipelining Tasks(流水线任务)
一个流水线就像一个过滤链,每一个阀门像一个过滤器。跟过滤器一样,一个阀门可以操作传递给它的request和response方法。
让一个阀门完成了处理,则进一步处理流水线中的下一个阀门,基本阀门总是在最后才被调用。
当容器的invoke方法被调用时,它不需要知道怎么去做,把这个问题交给pipeline(调用pipeline的invoke方法),看一下他们的接口。
//代表Valve上下文,包含一个Valve数组和baseValve。 public interface ValveContext { public String getInfo(); //调用下一个Valve public void invokeNext(Request request, Response response) throws IOException, ServletException; } //包含一个ValveContext public interface Pipeline { public Valve getBasic();//获取base Valve public void setBasic(Valve valve);//设置base Valve public void addValve(Valve valve);//增加一个Valve public Valve[] getValves();//获取全部的Valve //container会调用该方法,把问题交给pipeline处理,pipeline在这里会调用ValveContext的invokeNext方法 public void invoke(Request request, Response response) throws IOException, ServletException; public void removeValve(Valve valve);//删除一个Valve } public interface Valve { public String getInfo(); //ValveContext会调用这个方法 public void invoke(Request request, Response response, ValveContext context) throws IOException, ServletException; } //一个Valve类可以选择实现该接口,表明这个Valve的实现和至多一个容器绑定在了一起。 public interface Contained { public Container getContainer(); public void setContainer(Container container); }
一个container有一个pipeline. container的invoke方法调用pipeline的invoke方法.
//container public void invoke(Request request, Response response) throws IOException, ServletException { pipeline.invoke(request, response); }
pipeline的invoke方法调用container中所有valve然后调用container的basic valve的invoke方法
//pipeline 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); } protected class SimplePipelineValveContext implements ValveContext { protected int stage = 0; 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
在一个wrapper中, basic valve负责加载与之一对一关联的servlet类,并响应请求.
public void invoke(Request request, Response response, ValveContext valveContext) throws IOException, ServletException { SimpleWrapper wrapper = (SimpleWrapper) getContainer(); Servlet servlet = null; try { //加载servlet servlet = wrapper.allocate(); //处理请求 servlet.service(request.getRequest(), response.getResponse()); } catch (ServletException e){} }
浙公网安备 33010602011771号