【目錄】本文主要講解Tomcat啓動和部署webapp時的原理和過程,以及其使用的配置文件的詳解。主要有三大部分:html
第一部分、Tomcat的簡介和啓動過程java
第二部分、Tomcat部署webappmysql
第三部分、Tomcat處理一個http請求的過程web
【簡介】sql
Tomcat依賴<CATALINA_HOME>/conf/server.xml這個配置文件啓動server(一個Tomcat實例,核心就是啓動容器Catalina)。數據庫
Tomcat部署Webapp時,依賴context.xml和web.xml(<CATALINA_HOME>/conf/目錄下的context.xml和web.xml在部署任何webapp時都會啓動,他們定義一些默認行爲,而具體每一個webapp的 META-INF/context.xml 和 WEB-INF/web.xml 則定義了每一個webapp特定的行爲)兩個配置文件部署web應用。apache
第一部分、Tomcat的簡介和啓動過程
1、Tomcat的下載包解壓以後的目錄windows
tomcat根目錄在tomcat中叫<CATALINA_HOME>瀏覽器
<CATALINA_HOME>/bin:存放各類平臺下啓動和關閉Tomcat的腳本文件.其中 有個檔是catalina.bat,打開這個windos配置文件,在非註釋行加入JDK路徑,例如 : SET JAVA_HOME=C:\j2sdk1.4.2_06 保存後,就配置好tomcat環境了. startup.bat是windows下啓動tomcat的文件,shutdown.bat是關閉tomcat的文件.tomcat
<CATALINA_HOME>/conf:存放不一樣的配置文件(如:server.xml和web.xml);
server.xml文件:該文件用於配置和server相關的信息,好比tomcat啓動的端口號、配置host主機、配置Context
web.xml文件:部署描述文件,這個web.xml中描述了一些默認的servlet,部署每一個webapp時,都會調用這個文件,配置該web應用的默認servlet。
tomcat-users.xml文件:配置tomcat的用戶密碼與權限。
context.xml:定義web應用的默認行爲。
<CATALINA_HOME>/lib:存放Tomcat運行須要的庫文件(JARS);
<CATALINA_HOME>/logs:存放Tomcat執行時的LOG文件;
<CATALINA_HOME>/temp:
<CATALINA_HOME>/webapps:Tomcat的主要Web發佈目錄(包括應用程序示例);
<CATALINA_HOME>/work:存放jsp編譯後產生的class文件;
2、Tomcat啓動過程
一、開啓Tomcat:能夠在IDE中啓動Tomcat的服務器,也能夠手動在<CATALINA_HOME>/bin/目錄下找到startup.bat並雙擊,而後程序就會依次執行如下步驟:
(1)引導(Bootstrap)啓動:調用了org.apache.catalina.startup.Bootstrap.class中的main方法,開始啓動Tomcat容器;main方法以下:
public static void main(String args[]) { if (daemon == null) { daemon = new Bootstrap();//建立了一個引導對象 try {//引導對象初始化,即建立了Catalina容器 daemon.init(); } catch (Throwable t) { t.printStackTrace(); return; } } // 根據不一樣的命令參數執行 try { String command = "start"; if (args.length > 0) { command = args[args.length - 1]; } if (command.equals("startd")) { args[args.length - 1] = "start"; daemon.load(args); daemon.start(); } else if (command.equals("stopd")) { args[args.length - 1] = "stop"; daemon.stop(); } else if (command.equals("start")) { daemon.setAwait(true); daemon.load(args); daemon.start(); } else if (command.equals("stop")) { daemon.stopServer(args); } else { log.warn("Bootstrap: command \"" + command + "\" does not exist."); } } catch (Throwable t) { t.printStackTrace(); } } public void init() throws Exception { // Set Catalina path // 設置catalina_home屬性,tomcat啓動腳本里有經過-Dcatalina.home設置 setCatalinaHome(); // 設置catalina_base屬性,運行多實例的時候該目錄與catalina_home不一樣 setCatalinaBase(); // 初始化classloader,讀取conf/catalina.properties,根據指定的repository建立classloader // 有三個classloader 分別是common、catalina、shared,tomcat6中三個相同 initClassLoaders(); // 設置當前線程的classloader Thread.currentThread().setContextClassLoader(catalinaLoader); // 待研究 SecurityClassLoad.securityClassLoad(catalinaLoader); // 如下經過反射調用Catalina中的方法 // Load our startup class and call its process() method if (log.isDebugEnabled()) log.debug("Loading startup class"); Class startupClass = catalinaLoader.loadClass ("org.apache.catalina.startup.Catalina"); Object startupInstance = startupClass.newInstance(); // Set the shared extensions class loader if (log.isDebugEnabled()) log.debug("Setting startup class properties"); String methodName = "setParentClassLoader"; Class paramTypes[] = new Class[1]; paramTypes[0] = Class.forName("java.lang.ClassLoader"); Object paramValues[] = new Object[1]; paramValues[0] = sharedLoader; Method method = startupInstance.getClass().getMethod(methodName, paramTypes); method.invoke(startupInstance, paramValues); catalinaDaemon = startupInstance; }
2)調用Bootstrap中的init(),建立了Catalina對象(核心容器):主要進行了如下三步:
① Set up the environment variables required by this Tomcat instance
② Instantiate the general class loaders that will be used for our running Tomcat instance
③ Initialize this Tomcat instance
(3)調用Bootstrap中的load():其實是經過反射調用了catalina的load方法。
①Parse the main configuration file for a Tomcat instance, server.xml, converting each configuration element into the appropriate Tomcat component1。(找到config file(server.xml);而後建立digester,解析server.xml,生成各組件對象(Server、Service、Container、Connector等)以及創建相互之間的關係。 )
// Configure the actions we will be using digester.addObjectCreate("Server", "org.apache.catalina.core.StandardServer", "className"); digester.addSetProperties("Server"); digester.addSetNext("Server", "setServer", "org.apache.catalina.Server"); digester.addObjectCreate("Server/GlobalNamingResources", "org.apache.catalina.deploy.NamingResources"); digester.addSetProperties("Server/GlobalNamingResources"); digester.addSetNext("Server/GlobalNamingResources", "setGlobalNamingResources", "org.apache.catalina.deploy.NamingResources"); digester.addObjectCreate("Server/Listener", null, // MUST be specified in the element "className"); digester.addSetProperties("Server/Listener"); digester.addSetNext("Server/Listener", "addLifecycleListener", "org.apache.catalina.LifecycleListener"); digester.addObjectCreate("Server/Service", "org.apache.catalina.core.StandardService", "className"); digester.addSetProperties("Server/Service"); digester.addSetNext("Server/Service", "addService", "org.apache.catalina.Service"); digester.addObjectCreate("Server/Service/Listener", null, // MUST be specified in the element "className"); digester.addSetProperties("Server/Service/Listener"); digester.addSetNext("Server/Service/Listener", "addLifecycleListener", "org.apache.catalina.LifecycleListener"); //Executor digester.addObjectCreate("Server/Service/Executor", "org.apache.catalina.core.StandardThreadExecutor", "className"); digester.addSetProperties("Server/Service/Executor"); digester.addSetNext("Server/Service/Executor", "addExecutor", "org.apache.catalina.Executor"); digester.addRule("Server/Service/Connector", new ConnectorCreateRule()); digester.addRule("Server/Service/Connector", new SetAllPropertiesRule(new String[]{"executor"})); digester.addSetNext("Server/Service/Connector", "addConnector", "org.apache.catalina.connector.Connector"); // ...
(4)Start up our outermost Top Level Element—the Server instance。(最後start(),一樣是在Bootstrap中經過反射調用catalina對象的start方法。接着啓動server.start()方法:((Lifecycle) getServer()).start(); 接着調用service.start()方法。接下來是一系列的container的start,後續在分析(會部署全部的項目)
public void start() { if (getServer() == null) { load(); } if (getServer() == null) { log.fatal("Cannot start server. Server instance is not configured."); return; } long t1 = System.nanoTime(); // Start the new server if (getServer() instanceof Lifecycle) { try { ((Lifecycle) getServer()).start(); } catch (LifecycleException e) { log.error("Catalina.start: ", e); } } long t2 = System.nanoTime(); if(log.isInfoEnabled()) log.info("Server startup in " + ((t2 - t1) / 1000000) + " ms"); try { // Register shutdown hook if (useShutdownHook) { if (shutdownHook == null) { shutdownHook = new CatalinaShutdownHook(); } Runtime.getRuntime().addShutdownHook(shutdownHook); // If JULI is being used, disable JULI's shutdown hook since // shutdown hooks run in parallel and log messages may be lost // if JULI's hook completes before the CatalinaShutdownHook() LogManager logManager = LogManager.getLogManager(); if (logManager instanceof ClassLoaderLogManager) { ((ClassLoaderLogManager) logManager).setUseShutdownHook( false); } } } catch (Throwable t) { // This will fail on JDK 1.2. Ignoring, as Tomcat can run // fine without the shutdown hook. } if (await) { await(); stop(); } }
(5)Set up a shutdown hook
A shutdown hook is a standard Thread that encapsulates cleanup actions that should be taken before the Java runtime exits. All shutdown hooks are called by the runtime when the JVM is shutting down.
Therefore, the last task that we perform is to install a shutdown hook, as implemented by CatalinaShutdownHook. This hook is registered with the Java Runtime by invoking its addShutdownHook() method:
Runtime.getRuntime().addShutdownHook(),
// Register shutdown hook if (useShutdownHook) { if (shutdownHook == null) { shutdownHook = new CatalinaShutdownHook(); } Runtime.getRuntime().addShutdownHook(shutdownHook); // If JULI is being used, disable JULI's shutdown hook since // shutdown hooks run in parallel and log messages may be lost // if JULI's hook completes before the CatalinaShutdownHook() LogManager logManager = LogManager.getLogManager(); if (logManager instanceof ClassLoaderLogManager) { ((ClassLoaderLogManager) logManager).setUseShutdownHook( false); } }
3、server.xml配置簡介:
下面講述這個文件中的基本配置信息,更具體的配置信息請參考tomcat的文檔:
4、web.xml配置簡介:
一、默認(歡迎)文件的設置
在tomcat4\conf\web.xml中,<welcome-file-list>與IIS中的默認文件意思相同。
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
二、報錯文件的設置
<error-page>
<error-code>404</error-code>
<location>/notFileFound.jsp</location>
</error-page>
<error-page>
<exception-type>java.lang.NullPointerException</exception-type>
<location>/null.jsp</location>
</error-page>
若是某文件資源沒有找到,服務器要報404錯誤,按上述配置則會調用\webapps\ROOT\notFileFound.jsp。
若是執行的某個JSP文件產生NullPointException ,則會調用\webapps\ROOT\null.jsp
三、會話超時的設置
設置session 的過時時間,單位是分鐘;
<session-config>
<session-timeout>30</session-timeout>
</session-config>
四、過濾器的設置
<filter>
<filter-name>FilterSource</filter-name>
<filter-class>project4. FilterSource </filter-class>
</filter>
<filter-mapping>
<filter-name>FilterSource</filter-name>
<url-pattern>/WwwServlet</url-pattern>
(<url-pattern>/haha/*</url-pattern>)
</filter-mapping>
過濾:
1) 身份驗證的過濾Authentication Filters
2) 日誌和審覈的過濾Logging and Auditing Filters
3) 圖片轉化的過濾Image conversion Filters
4) 數據壓縮的過濾Data compression Filters
5) 加密過濾Encryption Filters
6) Tokenizing Filters
7) 資源訪問事件觸發的過濾Filters that trigger resource access events XSL/T 過濾XSL/T filters
9) 內容類型的過濾Mime-type chain Filter 注意監聽器的順序,如:先安全過濾,而後資源,
而後內容類型等,這個順序能夠本身定。
5、管理
一、用戶配置
在進行具體Tomcat管理以前,先給tomcat添加一個用戶,使這個用戶有權限來進行管理。
打開conf目錄下的tomcat-users.xml文件,在相應的位置添加下面一行:
<user name="user" password="user" roles="standard,manager"/>
而後重起tomcat,在瀏覽器中輸入http://localhost:8080/manager/,會彈出對話框,輸入上面的用戶
名和密碼便可。
二、應用程序列表
在瀏覽器中輸入http://localhost:8080/manager/list,瀏覽器將會顯示以下的信息:
OK - Listed applications for virtual host localhost
/ex:running:1
/examples:running:1
/webdav:running:0
/tomcat-docs:running:0
/manager:running:0
/:running:0
上面顯示的信息分別爲:應用程序的路徑、當前狀態、鏈接這個程序的session數
三、從新裝載應用程序
在瀏覽器中輸入 http://localhost:8080/manager/reload?path=/examples,瀏覽器顯示以下:
OK - Reloaded application at context path /examples
這表示example應用程序裝載成功,若是咱們將server.xml的Context元素的reloadable屬性設爲true,則不必利用這種方式從新裝載應用程序,由於tomcat會自動裝載。
四、顯示session信息
在瀏覽器中輸入http://localhost:8080/manager/sessions?path=/examples,瀏覽器顯示以下:
OK - Session information for application at context path /examples Default maximum session inactive
interval 30 minutes
五、啓動和關閉應用程序
在瀏覽器中輸入http://localhost:8080/manager/start?path=/examples和
http://localhost:8080/manager/stop?path=/examples分別啓動和關閉examples應用程序。
六 、 Tomcat Server的組成部分
1.1 – Server
A Server element represents the entire Catalina servlet container. (Singleton)
1.2 – Service
A Service element represents the combination of one or more Connector components that share a single Engine
Service是這樣一個集合:它由一個或者多個Connector組成,以及一個Engine,負責處理全部Connector所得到的客戶請求
1.3 – Connector
一個Connector將在某個指定端口上偵聽客戶請求,並將得到的請求交給Engine來處理,從Engine處得到迴應並返回客戶
TOMCAT有兩個典型的Connector,一個直接偵聽來自browser的http請求,一個偵聽來自其它WebServer的請求
Coyote Http/1.1 Connector 在端口8080處偵聽來自客戶browser的http請求
Coyote JK2 Connector 在端口8009處偵聽來自其它WebServer(Apache)的servlet/jsp代理請求
1.4 – Engine
The Engine element represents the entire request processing machinery associated with a particular Service
It receives and processes all requests from one or more Connectors
and returns the completed response to the Connector for ultimate transmission back to the client
Engine下能夠配置多個虛擬主機Virtual Host,每一個虛擬主機都有一個域名
當Engine得到一個請求時,它把該請求匹配到某個Host上,而後把該請求交給該Host來處理
Engine有一個默認虛擬主機,當請求沒法匹配到任何一個Host上的時候,將交給該默認Host來處理
1.5 – Host
表明一個Virtual Host,虛擬主機,每一個虛擬主機和某個網絡域名Domain Name相匹配
每一個虛擬主機下均可以部署(deploy)一個或者多個Web App,每一個Web App對應於一個Context,有一個Context path
當Host得到一個請求時,將把該請求匹配到某個Context上,而後把該請求交給該Context來處理
匹配的方法是「最長匹配」,因此一個path==」"的Context將成爲該Host的默認Context
全部沒法和其它Context的路徑名匹配的請求都將最終和該默認Context匹配
1.6 – Context
一個Context對應於一個Web Application,一個Web Application由一個或者多個Servlet組成
Context在建立的時候將根據配置文件$CATALINA_HOME/conf/web.xml和$WEBAPP_HOME/WEB-INF/web.xml載入Servlet類
當Context得到請求時,將在本身的映射表(mapping table)中尋找相匹配的Servlet類
若是找到,則執行該類,得到請求的迴應,並返回
2 – Tomcat Server的結構圖
【Tomcat的啓動過程】Tomcat 先根據/conf/server.xml 下的配置啓動Server,再加載Service,對於與Engine相匹配的Host,每一個Host 下面都有一個或多個Context。
注意:Context 既可配置在server.xml 下,也可配置成一單獨的文件,放在conf\Catalina\localhost 下,簡稱應用配置文件。
Web Application 對應一個Context,每一個Web Application 由一個或多個Servlet 組成。當一個Web Application 被初始化的時候,它將用本身的ClassLoader 對象載入部署配置文件web.xml 中定義的每一個Servlet 類:它首先載入在$CATALINA_HOME/conf/web.xml中部署的Servlet 類,而後載入在本身的Web Application 根目錄下WEB-INF/web.xml 中部署的Servlet 類。
web.xml 文件有兩部分:Servlet 類定義和Servlet 映射定義。
每一個被載入的Servlet 類都有一個名字,且被填入該Context 的映射表(mapping table)中,和某種URL 路徑對應。當該Context 得到請求時,將查詢mapping table,找到被請求的Servlet,並執行以得到請求響應。
因此,對於Tomcat 來講,主要就是如下這幾個文件:conf 下的server.xml、web.xml,以及項目下的web.xml,加載就是讀取這些配置文件。
3 – 配置文件$CATALINA_HOME/conf/server.xml的說明
該文件描述瞭如何啓動Tomcat Server
<!-----------------------------------------------------------------------------------------------> <!-- 啓動Server 在端口8005處等待關閉命令 若是接受到"SHUTDOWN"字符串則關閉服務器 --> <Server port="8005" shutdown="SHUTDOWN" debug="0"> <!-- Listener ??? 目前沒有看到這裏 --> <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" debug="0"/> <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" debug="0"/> <!-- Global JNDI resources ??? 目前沒有看到這裏,先略去 --> <GlobalNamingResources> ... ... ... ... </GlobalNamingResources> <!-- Tomcat的Standalone Service Service是一組Connector的集合 它們共用一個Engine來處理全部Connector收到的請求 --> <Service name="Tomcat-Standalone"> <!-- Coyote HTTP/1.1 Connector className : 該Connector的實現類是org.apache.coyote.tomcat4.CoyoteConnector port : 在端口號8080處偵聽來自客戶browser的HTTP1.1請求 minProcessors : 該Connector先建立5個線程等待客戶請求, 每一個請求由一個線程負責 maxProcessors : 當現有的線程不夠服務客戶請求時,若線程總數不足75個,則建立新線程來處理請求 acceptCount : 當現有線程已經達到最大數75時,爲客戶請求排隊 當隊列中請求數超過100時,後來的請求返回Connection refused 錯誤 redirectport : 當客戶請求是https時,把該請求轉發到端口8443去 其它屬性略 --> <Connector className="org.apache.coyote.tomcat4.CoyoteConnector" port="8080" minProcessors="5" maxProcessors="75" acceptCount="100" enableLookups="true" redirectPort="8443" debug="0" connectionTimeout="20000" useURIValidationHack="false" disableUploadTimeout="true" /> <!-- Engine用來處理Connector收到的Http請求 它將匹配請求和本身的虛擬主機, 並把請求轉交給對應的Host來處理默認虛擬主機是localhost --> <Engine name="Standalone" defaultHost="localhost" debug="0"> <!-- 日誌類,目前沒有看到,略去先 --> <Logger className="org.apache.catalina.logger.FileLogger" .../> <!-- Realm,目前沒有看到,略去先 --> <Realm className="org.apache.catalina.realm.UserDatabaseRealm" .../> <!-- 虛擬主機localhost appBase : 該虛擬主機的根目錄是webapps/ 它將匹配請求和 本身的Context的路徑,並把請求轉交給對應的Context來處理 --> <Host name="localhost" debug="0" appBase="webapps" unpackWARs="true" autoDeploy="true"> <!-- 日誌類,目前沒有看到,略去先 --> <Logger className="org.apache.catalina.logger.FileLogger" .../> <!-- Context,對應於一個Web App path : 該Context的路徑名是"",故該Context是該Host的 默認Context docBase : 該Context的根目錄是webapps/mycontext/ --> <Context path="" docBase="mycontext" debug="0"/> <!-- 另一個Context,路徑名是/wsota --> <Context path="/wsota" docBase="wsotaProject" debug="0"/> </Host> </Engine> </Service> </Server> <!----------------------------------------------------------------------------------------------->
第二部分、Tomcat部署webapp
一、Context的部署配置文件web.xml的說明
一個Context對應於一個Web App,每一個Web App是由一個或者多個servlet組成的。
當一個Web App被初始化的時候,便會爲這個webapp建立一個context對象,並把這個context對象註冊到指定虛擬主機(host)上,接着,它將用 本身的ClassLoader對象載入「部署配置文件web.xml」中定義的每一個servlet類。它首先載入在$CATALINA_HOME/conf/web.xml中部署的servlet類,而後載入在本身的Web App根目錄下的WEB-INF/web.xml中部署的servlet類。
web.xml文件有兩部分:servlet類定義和servlet映射定義
每一個被載入的servlet類都有一個名字,且被填入該Context的映射表(mapping table)中,和某種URL PATTERN對應。當該Context得到請求時,將查詢mapping table,找到被請求的servlet,並執行以得到請求迴應
分析一下全部的Context共享的web.xml文件,在其中定義的servlet被全部的Web App載入
<!-----------------------------------------------------------------------------------------------> <web-app> <!-- 概述: 該文件是全部的WEB APP共用的部署配置文件, 每當一個WEB APP 被DEPLOY,該文件都將先被處理,而後纔是WEB APP本身的/WEB-INF/web.xml --> <!-- +-------------------------+ --> <!-- | servlet類定義部分 | --> <!-- +-------------------------+ --> <!-- DefaultServlet 當用戶的HTTP請求沒法匹配任何一個servlet的時候,該servlet被執行 URL PATTERN MAPPING : / --> <servlet> <servlet-name>default</servlet-name> <servlet-class> org.apache.catalina.servlets.DefaultServlet </servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <init-param> <param-name>listings</param-name> <param-value>true</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!-- InvokerServlet 處理一個WEB APP中的匿名servlet 當一個servlet被編寫並編譯放入 /WEB-INF/classes/中,卻沒有在/WEB-INF/web.xml中定義的時候 該servlet被調用,把匿名servlet映射成/servlet/ClassName的形式 URL PATTERN MAPPING : /servlet/* --> <servlet> <servlet-name>invoker</servlet-name> <servlet-class>org.apache.catalina.servlets.InvokerServlet </servlet-class> <init-param> <param-name>debug</param-name> <param-value>0</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> <!-- JspServlet 當請求的是一個JSP頁面的時候(*.jsp)該servlet被調用 它是一個JSP編譯器,將請求的JSP頁面編譯成爲servlet再執行 URL PATTERN MAPPING : *.jsp --> <servlet> <servlet-name>jsp</servlet-name> <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class> <init-param> <param-name>logVerbosityLevel</param-name> <param-value>WARNING</param-value> </init-param> <load-on-startup>3</load-on-startup> </servlet> <!-- +---------------------------+ --> <!-- | servlet映射定義部分 | --> <!-- +---------------------------+ --> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>invoker</servlet-name> <url-pattern>/servlet/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>jsp</servlet-name> <url-pattern>*.jsp</url-pattern> </servlet-mapping> <!-- +------------------------+ --> <!-- | 其它部分,略去先 | --> <!-- +------------------------+ --> ... ... ... ... </web-app> <!----------------------------------------------------------------------------------------------->
二、Context.xml和Context節點說明:
(1) 在tomcat 5.5以前
Context體如今/conf/server.xml中的<Host>裏的<Context>元素,它由Context接口定義。每一個<Context>元素表明了運行在虛擬主機上的單個Web應用
① path:即要創建的虛擬目錄,,注意是/kaka,訪問Web應用的 上下文根,如http://localhost:8080/kaka/****。這個屬性必須是惟一的,對應一個webapp。
② docBase:爲應用程序的路徑或WAR文件存放的路徑 ,能夠是絕對路徑 ,也但是相對路徑,相對路徑是相對於<Host >
③ reloadable:若是這個屬性設爲true,Tomcat服務器在運行狀態下會監視在WEB-INF/classes和Web-INF /lib目錄CLASS文件的改變,若是監視到有class文件被更新,服務器自動從新加載Web應用,這樣咱們能夠在不重起tomcat的狀況下改變應 用程序
一個Host元素中嵌套任意多的Context元素。每一個Context的路徑必須是唯一的,由path屬性定義。另外,你必須定義一個path=「」的context,這個Context稱爲該虛擬主機的缺省web應用,用來處理那些不能匹配任何Context的Context路徑的請求。
(2)在tomcat 5.5以後
不推薦在server.xml中進行配置,而是在/conf/context.xml中進行獨立的配置。因 爲 server.xml 是不可動態重加載的資源,服務器一旦啓動了之後,要修改這個文件,就得重啓服務器才能從新加載。而 context.xml 文件則否則, tomcat 服務器會定時去掃描這個文件。一旦發現文件被修改(時間戳改變了),就會自動從新加載這個文件,而不須要重啓服務器 。
<Context path="/kaka" docBase="kaka" debug="0" reloadbale="true" privileged="true"> <WatchedResource>WEB-INF/web.xml</WatchedResource> <WatchedResource>WEB-INF/kaka.xml</WatchedResource> 監控資源文件,若是web.xml || kaka.xml改變了,則自動從新加載改應用。 <Resource name="jdbc/testSiteds" 表示指定的jndi名稱 auth="Container" 表示認證方式,通常爲Container type="javax.sql.DataSource" maxActive="100" 鏈接池支持的最大鏈接數 maxIdle="30" 鏈接池中最多可空閒maxIdle個鏈接 maxWait="10000" 鏈接池中鏈接用完時,新的請求等待時間,毫秒 username="root" 表示數據庫用戶名 password="root" 表示數據庫用戶的密碼 driverClassName="com.mysql.jdbc.Driver" 表示JDBC DRIVER url="jdbc:mysql://localhost:3306/testSite" /> 表示數據庫URL地址 </Context>
(3)context.xml的三個做用範圍
① tomcat server級別:
在/conf/context.xml裏配置。(由於這個contex.xml是每一個webapp都會讀取的,因此在這個文件裏面定義的節點都是全局性的,即每一個webapp都會出現)
② Host級別:(有多個虛擬主機的時候纔會用到)
在/conf/Catalina/${hostName}裏添加context.xml,繼而進行配置
③ web app 級別:(這個context.xml是對應各自特定webapp的,屬於webapp內部)
在/conf/Catalina/${hostName}裏添加${webAppName}.xml,繼而進行配置(這個Context)
第三部分、Tomcat處理一個http請求的過程
1– Tomcat Server處理一個http請求的過程
假設來自客戶的請求爲:
http://localhost:8080/wsota/wsota_index.jsp
1) 請求被髮送到本機端口8080,被在那裏偵聽的Coyote HTTP/1.1 Connector得到
(1-1)Connector的主要任務是負責接收瀏覽器的發過來的 tcp 鏈接請求,建立一個 Request 和 Response 對象分別用於和請求端交換數據,而後會產生一個線程來處理這個請求並把產生的 Request 和 Response 對象傳給處理這個請求的線程
2) Connector把該請求交給它所在的Service的Engine來處理,並等待來自Engine的迴應
3) Engine得到請求localhost/wsota/wsota_index.jsp,匹配它所擁有的全部虛擬主機Host
4) Engine匹配到名爲localhost的Host(即便匹配不到也把請求交給該Host處理,由於該Host被定義爲該Engine的默認主機)
5) localhost Host得到請求/wsota/wsota_index.jsp,匹配它所擁有的全部Context
6) Host匹配到路徑爲/wsota的Context(若是匹配不到就把該請求交給路徑名爲」"的Context去處理)
7) path=」/wsota」的Context得到請求/wsota_index.jsp,在它的mapping table中尋找對應的servlet
8) Context匹配到URL PATTERN爲*.jsp的servlet,對應於JspServlet類
9) 構造HttpServletRequest對象和HttpServletResponse對象,做爲參數調用JspServlet的doGet或doPost方法
10)Context把執行完了以後的HttpServletResponse對象返回給Host
11)Host把HttpServletResponse對象返回給Engine
12)Engine把HttpServletResponse對象返回給Connector
13)Connector把HttpServletResponse對象返回給客戶browser
參考:http://docs.huihoo.com/apache/tomcat/heavyz/01-startup.html
from:http://www.cnblogs.com/mo-wang/p/3705147.html