Servlet容器
Container容器是用來處理Servlet請求,並構造向web客戶端發送的響應信息的模塊。容器用org.apache.catalina.Container接口來表示,主要有Engine、Host、Context和Wrapper四種類型,這裏先介紹Context和Wrapper。
Container接口
一個容器container必須實現org.apache.catalina.Container接口, 在連接器那一章中使用的一樣通過連接器的setContainer把容器實例傳過去,然後連接器就可以調用容器的invoke方法如下:
HttpConnector connector = new HttpConnector();
SimpleContainer container = new SimpleContainer();
connector.setContainer(container);
每一種容器都代表不同的概念級別:
1、 Engine:代表整個catalina servlet引擎
2、 Hoset:代表虛擬主機
3、 Context:代表一個應用
4、 Wrapper:代表一個獨立的servlet
每一個級別都在org.apache.catalina包下有對應接口來表示,分別是Engine、Host、Context和Wrapper,同時都有標準的實現類StandardEngine、StandardHost、StandardContext和StandardWrapper,具體見類圖:
一個Engine可以包含多個Host,一個Host可以包含多個Context,一個Context可以包含一個或多個Wrapper,Wrapper沒有子容器,
在容器中可以通過addChild添加子容器:
public void addChild(Container child);
通過removeChild方法可以刪除一個子容器:
public void removeChild(Container child);
通過findChild和findChildren可以查詢子容器:
public Container findChild(String name);
public Container[] findChildren();
管道任務(Pipeline tasks)
管道包含Container將會調用的任務,而任務是通過value來說明的,在管道中有一個基礎任務,同時你可以爲其添加多個任務,動態添加任務是通過修改server.xml來實現的。Task和value的實現原理類似於filter,task相當於filter chain,每個value就相當於一個filter,就像filter一樣,value也可以操縱request和response對象,一個value處理完了以後就會調用下一個value,basic value總是會被最後調用。
每一個container都包含一個Pipeline,一旦connector調用container的invoke方法以後,container都會交給它的pipeline來處理,Pipeline會調用它的第一個value,然後調用下一個value直到Pipeline中沒有value爲止,Container的invoke方法簽名如下:
public void invoke(Request request, Response response)
throws IOException, ServletException;
在ContainerBase中有其的實現:
public void invoke(Request request, Response response)
throws IOException, ServletException {
pipeline.invoke(request, response);
}
每個Pipeline都有一個內部類實現ValueContext接口,在Pipeline中有一個ValueContext實例,一旦Pipeline的invoke被調用它首先會去調用ValueContext的invokeNext方法:
public void invokeNext(Request request, Response response)
throws IOException, ServletException ;
在其中又會去調用Value的invoke方法:
public void invoke(Request request, Response response,
ValveContext context)
throws IOException, ServletException;
從中方法中可以看到,ValueContext會把自己傳進去,這樣Value就可以接着調用下一個Value直到調用Base vale的invoke方法爲止。
Pipeline接口
管道接口Pipeline除了有上面提到的invoke方法以外,還有添加和刪除value的addValue和removeValue方法,設置或獲取basic value的setBasic或getBasic方法,basic value的職責就是處理request和相應的response對象,Pipeline接口定義如下:
package org.apache.catalina;
import java.io.IOException;
import javax.servlet.ServletException;
public interface Pipeline {
public Valve getBasic();
public void setBasic(Valv e valve);
public void addValve(Valve valve);
public Valve[] getValves();
public void invoke(Request request, Response response)
throws IOException, ServletException;
public void removeValve(Valve valve);
}
Value接口
Value是用來處理request的,除了invoke方法外,還有getInfo方法獲取Value的一些描述信息:
package org.apache.catalina;
import java.io.IOException;
import javax.servlet.ServletException;
public interface Valve {
public String getInfo();
public void invoke(Request request, Response response,
ValveContext context)throws IOException, ServletException;
}
ValueContext接口
ValueContext處理invokeNext方法外,也有一個getInfo方法,接口定義如下:
package org.apache.catalina;
import java.io.IOException;
import javax.servlet.ServletException;
public interface ValveContext {
public String getInfo();
public void invokeNext(Request request, Response response)throws IOException, ServletException;
}
Contained接口
每個Value都可以選擇性的實現org.apache.catalina.Contained接口,表示該Value至少分配給一個Container。
public interface Contained {
public Container getContainer();
public void setContainer(Container container);
}
Wrapper接口
Wrapper是Tomcat中的一種容器類型,該類型不能在添加子容器,用org.apache.catalina.Wrapper接口表示,用來管理servlet的生命週期。主要有兩個方法allocate和load,allocate方法用來定位和初始化servlet的地址,load用來加載servlet,方法聲明如下:
public Servlet allocate() throws ServletException;
public void load() throws ServletException;
並提供了Wrapper的標準實現類StandardWrapper
Context接口
Context代表一個web應用,可以包含一個或多個Wrapper,其中包含兩個重要的方法:addWrapper和createWrapper。