日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

(精)tomcat 源码学习

發布時間:2024/4/14 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 (精)tomcat 源码学习 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Tomcat6是最新版本的web容器,其支持最新版本的servlet2.5jsp2.1。而且Tomcat6架構也是經過重新設計優化過的,所以我們有必要分析一下它的架構過程。顯然,這是一個通過閱讀Tomcat的源代碼及相關文檔,演繹架構的過程。或許有人會說,這不是放馬后炮嗎?!!但我覺得這是自我進步的一個必經步驟,先模仿之,然后才能超越之,畢竟我本凡人。

Tomcat的架構總的來說是分層次的、可插拔的組件架構。分層次是指構成Tomcat的組件不是同一級別的,上層組件可以包含子組件,各個組件有其功能范圍,當一個組件停止服務時,不會影響上層組件的服務。可插拔是指對于組件的添加和刪除并不影響服務器的運行。那么為了達到可插拔的組件架構,分層次的組件架構必成為基礎。

對于任何服務器,即使最簡單的實現,從面向對象設計(OOD)的角度來說,我們都有必要將“服務器”這個概念抽象出來,為什么呢?因為只有有了這個概念,才能談服務器的實例,服務器的功能等等其它概念,此之謂“皮之不存,毛將焉附”。趕巧(其實是我的想法恰好撞上人家的想法),Tomcat也將“服務器”抽象為java接口org.apache.catalina.Server,顯然Server應該就是最最頂層的組件了。

有了Server這個抽象,很自然的,我們希望它能夠提供對servletjsp支持的功能。但是我們發現這個概念太大了,我們還需再細化。所以別急,我們還有一些事情要解決。服務器要提供服務就必須能夠啟動,當然也應該能夠停止吧,也就是說服務器應該是有生命的,在啟動時初始化必要的資源,而在停止時將其其銷毀掉。好吧,我們把這個也抽象出來,叫做生命周期接口,tomcat?實現為org.apache.catalina.Lifecycle.如上所述我們知道Lifecycle需要完成的工作了。

public?void?start()?throws?LifecycleException;

public?void?stop()?throws?LifecycleException;

接下來我們分析服務器如何來處理客戶端的請求,一般的我們會在瀏覽器中輸入如下格式的請求,http://192.168.8.221:8080/explorer/loginInit.do。對于服務器來說,要想處理這個請求,就必須監聽指定的端口8080,當有TCP的請求包來時,建立Socket連接,分析并解析之,然后給客戶端返回響應。在這個過程中,我們發現,其實包含了倆個功能點,即監聽并接受請求和處理請求。那么我們能否將這倆個功能給抽象出來呢?Tomcat告訴我們,可以。是的,Tomcat將“監聽并接收請求”抽象為org.apache.catalina.connector.Connector類,負責接受請求;將“處理請求”抽象為“容器”org.apache.catalina.Container,負責處理Connector傳遞過來的請求。

Ok,到此,我們分析構建的簡單服務器模型出來了,ServerConnector組件和Container組件結合提供web服務。

2

有了這個模型后,要實現一個簡單的Server已經很簡單了,但是在實現Container時,我們還是要做很多事情,如當來請求,我們怎么知道該請求對應得虛擬主機,以及請求的那個應用,應該交給那個servlet對象來處理?這樣看來,Container還是太大了,需要細化。根據Servlet規范,我們知道,servlet屬于某個應用,且有上下文環境,Container要根據應用上下文環境初始化servlet,然后根據servlet映射調用servletservice方法。在這里“應用上下文環境”的概念很重要,Tomcat將其抽象為org.apache.catalina.ContextContext繼承了Container接口。對于虛擬主機,Tomcat將其抽象為org.apache.catalina.HostHost繼承了Container接口。

好了,有了這些概念,我們再回顧一下請求的處理過程:瀏覽器發出請求,Connector接受請求,將請求交由Container處理,Container查找請求對應的Host并將請求傳遞給它,Host拿到請求后查找相應的應用上下文環境,準備servlet環境并調用service方法。

現在,我們的服務器模型變成了如圖3所示了。

3

但是在Tomcat的實現體系中還有一個Engine的接口,Engine也繼承了Container接口,那么這個接口什么用呢?設計Engine的目的有倆個目的,一,當希望使用攔截器查看(過濾或預處理)每個請求時,Engine是個很好的攔截點。二,當希望多個虛擬Host共享一個HttpConnector時,Engine是個很好的門面。所以,Engine接口是作為頂級Container組件來設計的,其作用相當于一個Container的門面。有了Engine,請求的處理過程變為:瀏覽器發出請求,Connector接受請求,將請求交由Container(這里是Engine)處理,ContainerEngine來擔當)查找請求對應的Host并將請求傳遞給它,Host拿到請求后查找相應的應用上下文環境,準備servlet環境并調用service方法。再看看服務器的模型,如圖4.

4

到目前,我們碰到的組件類型有ConnectorContainer,其實,這也就是Tomcat的核心組件。如圖4,一組Connector和一個Container有機的組合在一起構成Server,就可以提供服務了,對于Tomcat來說,主要是提供Servlet服務,那么也就是說Tomcat服務器也可以提供其它服務了?是的,Tomcat將“一組Connector和一個Container有機的組合”抽象為“服務”接口org.apache.catalina.Service,然而,這些服務實例彼此獨立,僅僅共享JVM的基礎設施,如系統類路徑。

進一步的,我們得到了服務器的框架模型,如圖5.

5

????由圖5,我們知道,對于Tomcat服務器來說,除了Server代表它自己以外,其它組件都是功能組件,都有其職責范圍。Service為最頂層的組件,可以添加ConnectorContainer組件。EngineContainer的最頂層組件,可以添加Host組件,但不能添加父組件。Host組件的父組件是EngineHost下面包含有Context組件。

????接下來看看標準的Tomcat體系結構,如圖6.

6

比較圖5和圖6.我們發現,還有很多輔助組件沒有抽象出來。當然,隨著需求的一步步加深,我的分析也會一步步深入,這些個組件也會慢慢浮出水面。

?

以上轉自:http://blog.163.com/haizai219@126/blog/static/4441255520098841540516/

-------------------------------------------------------------------------------------------------------------------------------------

?

Tomcat從5.5版本開始,支持以下四種Connector的配置分別為 NIO, HTTP, POOL, NIOP:

<Connector port="8081" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" redirectPort="8443"/>

<Connector port="8081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443"/>

<Connector executor="tomcatThreadPool"port="8081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />

<Connector executor="tomcatThreadPool" port="8081" protocol="org.apache.coyote.http11.Http11NioProtocol" connectionTimeout="20000" redirectPort="8443" />

?

NetworkClient

? ? ? ? -->Socket-->PlainSocketImpl的native void socketConnect(InetAddress paramInetAddress, int paramInt1, int paramInt2)

?

NetworkServer

? ? ? ? 帶main方法的ServerSocket

?

HttpURLConnection

? ? ? ? -->HttpClient extends NetworkClient

?

?

tomcat 如何通過jmx loader 、digester架構

一、目錄結構:

? ? ? ? apache-tomcat-5.5.23\server\lib

? ? ? ? apache-tomcat-5.5.23\common\lib

? ? ? ? conf\context.xml

? ? ? ? ? ? ? ? <Context><WatchedResource>WEB-INF/web.xml</WatchedResource></Context>

? ? ? ? conf\web.xml

? ? ? ? ? ? ? ? 這個里面的加載 ? ? ? ? ? ? ? ?

? ? ? ? jasper-compiler.jar負責把index_jsp轉化成index_jsp.servlet,(當首次訪問該jsp時)

? ? ? ? ? ? ? ? apache-tomcat-5.5.23\work\Catalina\localhost\myservlet\org\apache\jsp\index_jsp

?

二、

conf\server.xml元素結構

<Server port="8005" shutdown="SHUTDOWN">

? ? ? ? <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener"/>

? ? ? ? <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>

? ? ? ? <Service name="Catalina">

? ? ? ? ? ? ? ? //1、端口。將port=80,進入本地服務時就不用敲80在末尾了(瀏覽器默認),這樣當安裝了IIS服務(80端口)時,tomcat無法啟動(它是serversocket)。

? ? ? ? ? ? ? ? <Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol" redirectPort="8443" useBodyEncodingForURI="true"/>

? ? ? ? ? ? ? ? <Engine defaultHost="localhost" name="Catalina">

? ? ? ? ? ? ? ? ? ? ? ? <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <Context docBase="mypushlet" path="/mypushlet" reloadable="true" source="org.eclipse.jst.jee.server:mypushlet"/>

? ? ? ? ? ? ? ? ? ? ? ? </Host>

? ? ? ? ? ? ? ? </Engine>

? ? ? ? </Service>

</Server>

2.虛擬目錄:所有的開發程序【JSP、servlet文件】保存在虛擬目錄中。

? ? ? ? 設虛擬目錄 "myweb",通過 http://localhost:8080/myweb 訪問物理路徑 L:\java\JWeb 文件夾里面的內容。設置過程如下:?

? ? ? ? 1.復制 Tomcat6.0\webapps\ROOT 目錄下的 WEB-INF 文件夾到 L:\java\JWeb 目錄下。?

? ? ? ? 2.打開L:\java\JWeb\WEB-INF 目錄下的 web.xml 文件,在 </description> 之后加入:?

? ? ? ? <!--JSPC servlet mappings start -->?

? ? ? ? <!--JSPC servlet mappings end -->?

? ? ? ? 3.打開 Tomcat6.0\conf\server.xml 文件,在 <Host> 和 </Host> 之間加入:?

? ? ? ? <Context path="/myweb" docBase="L:\java\JWeb"></Context>?

? ? ? ? path="/myweb" 就是虛擬目錄的名稱?

? ? ? ? docBase="L:\java\JWeb"> 為物理路徑?

? ? ? ? 4.打開 Tomcat6.0\conf\web.xml 文件,找到:?

? ? ? ? <init-param>?

? ? ? ? <param-name>listings</param-name>?

? ? ? ? <param-value>false</param-value>?

? ? ? ? </init-param>?

? ? ? ? 把false設成true保存,重啟Tomcat,現在就可以應用 http://localhost:8080/myweb 虛擬目錄了。?

? ? ? ? 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處獲得回應并返回客戶。?

? ? ? ? Coyote Http/1.1 Connector 在端口8080處偵聽來自客戶browser的http請求?

? ? ? ? Coyote JK2 Connector 在端口8009處偵聽來自其它WebServer(Apache)的servlet/jsp代理請求?

?

? ? ? ? 1.4 - Engine?

? ? ? ? An Engine is a Container that represents the entire Catalina servlet engine.?

? ? ? ? If used, an Engine is always the top level Container in a Catalina.

? ? ? ? Engine下可以配置多個虛擬主機Virtual Host,每個虛擬主機都有一個域名。?

? ? ? ? 當Engine獲得一個請求時,它把該請求匹配到某個Host上,然后把該請求交給該Host來處理

?

? ? ? ? 1.5 - Host?

?

架構:

? ? ? ? Server: 其實就是BackGroud程序, 在Tomcat里面的Server的用處是啟動和監聽服務端事件(諸如重啟、關閉等命令。SHUTDOWN)

? ? ? ? Service: 一類問題的解決方案。默認使用Tomcat-Standalone 模式的service。既給我們提供解析jsp和servlet的服務, 同時也提供給我們解析靜態文本的服務。

?

? ? ? ? Connector:從socket傳遞過來的數據, 封裝成Request, 傳遞給容器來處理。http、https、ajp(apache與tomcat)三種

? ? ? ? ? ? ? ? Container: 當http connector把需求傳遞給頂級的container: Engin的時候, 我們的視線就應該移動到Container這個層面來了。

? ? ? ? ? ? ? ? 在Container這個層, 我們包含了3種容器: Engin, Host, Context.

? ? ? ? ? ? ? ? Engin: 收到service傳遞過來的需求, 處理后, 將結果返回給service( service 是通過 connector 這個媒介來和Engin互動的 ).

? ? ? ? ? ? ? ? Host: Engin收到service傳遞過來的需求后,不會自己處理, 而是交給合適的Host來處理。

? ? ? ? ? ? ? ? Host在這里就是虛擬主機的意思, 通常我們都只會使用一個主機,既“localhost”本地機來處理。?

? ? ? ? ? ? ? ? Context: 一個web app,Host接到了從Host傳過來的需求后, 也不會自己處理, 而是交給合適的Context來處理。?

?

? ? ? ? Compenent: 容器有各種各樣的組件, 提供各種各樣的增值服務。

? ? ? ? ? ? ? ? manager: 當一個容器里面裝了manager組件后,這個容器就支持session管理了, 事實上在tomcat里面的session管理, 就是靠的在context里面裝的manager component.

? ? ? ? ? ? ? ? logger: 當一個容器里面裝了logger組件后

? ? ? ? ? ? ? ? loader: 通常只會給我們的context容器使用, loader是用來啟動context以及管理這個context的classloader用的。

? ? ? ? ? ? ? ? pipline: 容器間傳遞并過濾。

2. Tomcat的啟動流程: 第一步是裝配工作(父容器裝上子容器,容器安插進組件)。 第二步是啟動工作。?

?

?

2.3 Catalina.java

? ? ? ? 1. 使用Digester技術裝配tomcat各個容器與組件。

? ? ? ? ? ? ? ? 1.1 裝配工作的主要內容是安裝各個大件。 比如server下有什么樣的servcie。 Host會容納多少個context。 Context都會使用到哪些組件等等。?

? ? ? ? ? ? ? ? 1.2 同時呢, 在裝配工作這一步, 還完成了mbeans的配置工作。 在這里,我簡單地但不十分精確地描述一下mbean是什么,干什么用的。

? ? ? ? ? ? ? ? 我們自己生成的對象, 自己管理, 天經地義! 但是如果我們創建了對象了, 想讓別人來管, 怎么辦呢? 我想至少得告訴別人我們都有什么, 以及通過什么方法可以找到 吧! JMX技術給我們提供了一種手段。 JMX里面主要有3種東西。Mbean, agent, connector.

? ? ? ? ? ? ? ? Mbean: 用來映射我們的對象。也許mbean就是我們創建的對象, 也許不是, 但有了它, 就可以引用到我們的對象了。

? ? ? ? ? ? ? ? Agent: 通過它, 就可以找到mbean了。

? ? ? ? ? ? ? ? Connector: 連接Agent的方式。 可以是http的, 也可以是rmi的,還可以直接通過socket。

? ? ? ? ? ? ? ? 發生在tomcat 裝配過程中的事情: GlobalResourcesLifecycleListener 類的初始化會被觸發:

? ? ? ? ? ? ? ? protected static Registry registry = MBeanUtils.createRegistry(); 會運行

? ? ? ? ? ? ? ? MBeanUtils.createRegistry() 會依據/org/apache/catalina/mbeans/mbeans-descriptors.xml這個配置文件創建 mbeans. Ok, 外界就有了條途徑訪問tomcat中的各個組件了。

? ? ? ? 2. 為top level 的server 做初始化工作。 實際上就是做通常會配置給service的兩條connector.(http, ajp)

? ? ? ? 3. 從server這個容器開始啟動, 點燃整個tomcat.

? ? ? ? 4. 為server做一個hook程序, 檢測當server shutdown的時候, 關閉tomcat的各個容器用。

? ? ? ? 5. 監聽8005端口, 如果發送"SHUTDOWN"(默認培植下字符串)過來, 關閉8005serverSocket。

2.4 啟動各個容器

? ? ? ? 1. Server

? ? ? ? ? ? ? ? 觸發Server容器啟動前(before_start), 啟動中(start), 啟動后(after_start)3個事件, 并運行相應的事件處理器。

? ? ? ? ? ? ? ? 啟動Server的子容器:Servcie.?

? ? ? ? 2. Service

? ? ? ? ? ? ? ? 啟動Service的子容器:Engin

? ? ? ? ? ? ? ? 啟動Connector

? ? ? ? 3. Engin

? ? ? ? ? ? ? ? 到了Engin這個層次,以及以下級別的容器, Tomcat就使用了比較一致的啟動方式了。

? ? ? ? ? ? ? ? 首先, 運行各個容器自己特有一些任務

? ? ? ? ? ? ? ? 隨后, 觸發啟動前事件

? ? ? ? ? ? ? ? 立即, 設置標簽,就表示該容器已經啟動

? ? ? ? ? ? ? ? 接著, 啟動容器中的各個組件: loader, logger, manager等等

? ? ? ? ? ? ? ? 再接著,啟動mapping組件。(注1)

? ? ? ? ? ? ? ? 緊跟著,啟動子容器。

? ? ? ? ? ? ? ? 接下來,啟動該容器的管道(pipline)

? ? ? ? ? ? ? ? 然后, 觸發啟動中事件

? ? ? ? ? ? ? ? 最后, 觸發啟動后事件。

? ? ? ? ? ? ? ? Engin大致會這么做, Host大致也會這么做, Context大致還是會這么做。 那么很顯然地, 我們需要在這里使用到代碼復用的技術。 tomcat在處理這個問題的時候, 漂亮地使用了抽象類來處理。 ContainerBase. 最后使得這部分完成復雜功能的代碼顯得干凈利落, 干練爽快, 實在是令人覺得嘆為觀止, 細細品來, 直覺如享佳珍, 另人齒頰留香, 留戀往返啊!

? ? ? ? ? ? ? ? Engin的觸發啟動前事件里, 會激活綁定在Engin上的唯一一個Listener:EnginConfig。

? ? ? ? ? ? ? ? 這個EnginConfig類基本上沒有做什么事情, 就是把EnginConfig的調試級別設置為和Engin相當。 另外就是輸出幾行文本, 表示Engin已經配置完畢, 并沒有做什么實質性的工作。

? ? ? ? ? ? ? ? 注1: mapping組件的用處是, 當一個需求將要從父容器傳遞到子容器的時候, 而父容器又有多個子容器的話, 那么應該選擇哪個子容器來處理需求呢? 這個由mapping 組件來定奪。

? ? ? ? 4. Host

? ? ? ? ? ? ? ? 同Engin一樣, 也是調用ContainerBase里面的start()方法, 不過之前做了些自個兒的任務,就是往Host這個容器的通道(pipline)里面, 安裝了一個叫做

? ? ? ? ? ? ? ? “org.apache.catalina.valves.ErrorReportValve”的閥門。

? ? ? ? ? ? ? ? 這個閥門的用處是這樣的: 需求在被Engin傳遞給Host后, 會繼續傳遞給Context做具體的處理。 這里需求其實就是作為參數傳遞的Request, Response。 所以在context把需求處理完后, 通常會改動response。 而這個org.apache.catalina.valves.ErrorReportValve的作用就是檢察response是否包含錯誤, 如果有就做相應的處理。

? ? ? ? 5. Context

? ? ? ? ? ? ? ? 到了這里, 就終于輪到了tomcat啟動中真正的重頭戲,啟動Context了。

? ? ? ? ? ? ? ? StandardContext.start() 這個啟動Context容器的方法被StandardHost調用.

? ? ? ? ? ? ? ? 5.1 webappResources 該context所指向的具體目錄

? ? ? ? ? ? ? ? 5.2 安裝defaultContex, DefaultContext 就是默認Context。 如果我們在一個Host下面安裝了DefaultContext,而且defaultContext里面又安裝了一個數據庫連接池資源的話。 那么其他所有的在該Host下的Context, 都可以直接使用這個數據庫連接池, 而不用格外做配置了。

? ? ? ? ? ? ? ? 5.3 指定Loader. 通常用默認的org.apache.catalina.loader.WebappLoader這個類。 ? Loader就是用來指定這個context會用到哪些類啊, 哪些jar包啊這些什么的。

? ? ? ? ? ? ? ? 5.4 指定 Manager. 通常使用默認的org.apache.catalina.session. StandardManager 。 Manager是用來管理session的。

? ? ? ? ? ? ? ? 其實session的管理也很好實現。 以一種簡單的session管理為例。 當需求傳遞過來的時候, 在Request對象里面有一個sessionId 屬性。 OK, 得到這個sessionId后, 我們就可以把它作為map的key,而value我們可以放置一個HashMap. HashMap里邊兒, 再放我們想放的東西。

? ? ? ? ? ? ? ? 5.5 postWorkDirectory (). Tomcat下面有一個work目錄。 我們把臨時文件都扔在那兒去。 這個步驟就是在那里創建一個目錄。 一般說來會在%CATALINA_HOME%/work/Standalone\localhost\ 這個地方生成一個目錄。

? ? ? ? ? ? ? ? 5.6 Binding thread。到了這里, 就應該發生 class Loader 互換了。 之前是看得見tomcat下面所有的class和lib. 接下來需要看得見當前context下的class。 所以要設置contextClassLoader, 同時還要把舊的ClassLoader記錄下來,因為以后還要用的。

? ? ? ? ? ? ? ? 5.7 啟動 Loader. 指定這個Context具體要使用哪些classes, 用到哪些jar文件。 如果reloadable設置成了true, 就會啟動一個線程來監視classes的變化, 如果有變化就重新啟動Context。

? ? ? ? ? ? ? ? 5.8 啟動logger

? ? ? ? ? ? ? ? 5.9 觸發安裝在它身上的一個監聽器。

? ? ? ? ? ? ? ? lifecycle.fireLifecycleEvent(START_EVENT, null);?

? ? ? ? ? ? ? ? 作為監聽器之一,ContextConfig會被啟動. ContextConfig就是用來配置web.xml的。 比如這個Context有多少Servlet, 又有多少Filter, 就是在這里給Context裝上去的。

? ? ? ? ? ? ? ? 5.9.1 defaultConfig. 每個context都得配置 tomcat/conf/web.xml 這個文件。

? ? ? ? ? ? ? ? 5.9.2 applicationConfig 配置自己的 WEB-INF/web.xml 文件

? ? ? ? ? ? ? ? 5.9.3 validateSecurityRoles 權限驗證。 通常我們在訪問/admin 或者/manager的時候,需要用戶要么是admin的要么是manager的, 才能訪問。 而且我們還可以限制那些資源可以訪問, 而哪些不能。 都是在這里實現的。

? ? ? ? ? ? ? ? 5.9.4 tldScan: 掃描一下, 需要用到哪些標簽(tag lab)

? ? ? ? ? ? ? ? 5.10 啟動 manager

? ? ? ? ? ? ? ? 5.11 postWelcomeFiles() 我們通常會用到的3個啟動文件的名稱:

? ? ? ? ? ? ? ? index.html、index.htm、index.jsp 就被默認地綁在了這個context上

? ? ? ? ? ? ? ? 5.12 listenerStart 配置listener

? ? ? ? ? ? ? ? 5.13 filterStart 配置 filter

? ? ? ? ? ? ? ? 5.14 啟動帶有<load-on-startup>1</load-on-startup>的Servlet.

? ? ? ? ? ? ? ? 順序是從小到大: 1,2,3… 最后是0

? ? ? ? ? ? ? ? 默認情況下, 至少會啟動如下3個的Servlet:?

? ? ? ? ? ? ? ? org.apache.catalina.servlets.DefaultServlet ??

? ? ? ? ? ? ? ? 處理靜態資源的Servlet. 什么圖片啊, html啊, css啊, js啊都找他

? ? ? ? ? ? ? ? org.apache.catalina.servlets.InvokerServlet

? ? ? ? ? ? ? ? 處理沒有做Servlet Mapping的那些Servlet.

? ? ? ? ? ? ? ? org.apache.jasper.servlet.JspServlet?

? ? ? ? ? ? ? ? 處理JSP文件的.

? ? ? ? ? ? ? ? 5.15 標識context已經啟動完畢,tomcat啟動完畢。

?

?

/**

?* A <b>Host</b> is a Container that represents a virtual host in the

?* Catalina servlet engine. ?It is useful in the following types of scenarios:

?* <ul>

?* <li>You wish to use Interceptors that see every single request processed

?* ? ? by this particular virtual host.

?* <li>You wish to run Catalina in with a standalone HTTP connector, but still

?* ? ? want support for multiple virtual hosts.

?* </ul>

?* In general, you would not use a Host when deploying Catalina connected

?* to a web server (such as Apache), because the Connector will have

?* utilized the web server's facilities to determine which Context (or

?* perhaps even which Wrapper) should be utilized to process this request.

?* <p>

?* The parent Container attached to a Host is generally an Engine, but may

?* be some other implementation, or may be omitted if it is not necessary.

?* <p>

?* The child containers attached to a Host are generally implementations

?* of Context (representing an individual servlet context).

?*/ ? ? ? ?

? ? ? ? 每個虛擬主機下都可以部署(deploy)一個或者多個Web App,每個Web App對應于一個Context,有一個Context path。?

? ? ? ? 當Host獲得一個請求時,將把該請求匹配到某個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類,如果找到,則執行該類,獲得請求的回應,并返回。?

?

? ? ? ? 1.7 - 示例

? ? ? ? browser發送請求到本機端口8080--> Connector --> Engine --> Host --> Context --> servlet 構造request、response --> Context --> Host --> Engine -- > connector --> browser

?

?

public final class Bootstrap{

? ? ? ? private static Bootstrap daemon = null;

? ? ? ? private Object catalinaDaemon;

? ? ? ? protected ClassLoader commonLoader;

? ? ? ? protected ClassLoader catalinaLoader;

? ? ? ? protected ClassLoader sharedLoader;//Webapp1Loader ?Webapp2Loader ...?

?

? ? ? ? public Bootstrap(){...}

? ? ? ? private void initClassLoaders(){...}

? ? ? ? catalinaDaemon = this.catalinaLoader.loadClass("org.apache.catalina.startup.Catalina").newInstance();

?

? ? ? ? public void start()throws Exception{

? ? ? ? ? ? ? ? Method method = this.catalinaDaemon.getClass().getMethod("start", (Class[])null);

? ? ? ? ? ? ? ? method.invoke(this.catalinaDaemon, (Object[])null);

? ? ? ? }

}

?

public class StandardService implements Lifecycle, Service, MBeanRegistration?

? ? protected Connector connectors[] = new Connector[0];

? ? protected ArrayList<Executor> executors = new ArrayList<Executor>();

? ? /**?

? ? ?* this holds the most recently added Engine.is generally an instance of Engine

? ? ?*/

? ? protected Container container = null;

? ? ? ? /**

? ? ?* The lifecycle event support for this component.

? ? ?*/

? ? private LifecycleSupport lifecycle = new LifecycleSupport(this);

? ? /**

? ? ?* The <code>Server</code> that owns this Service, if any.

? ? ?*/

? ? private Server server = null;

? ? /**

? ? ?* The property change support for this component.

? ? ?*/

? ? protected PropertyChangeSupport support = new PropertyChangeSupport(this);

? ? public void addConnector(Connector connector) {}

? ? ? ? public void addPropertyChangeListener(PropertyChangeListener listener) {}

? ? ? ? public void addExecutor(Executor ex) {}

? ? ? ? public void addLifecycleListener(LifecycleListener listener) {}

}

?

//embed [im'bed] 嵌入

public class Embedded ?extends StandardServic{

? ? ? ? public synchronized void addEngine(Engine engine) {}

}

//啟動Tomcat,就生成Catalina實例,server實例????

根據配置文件server.xml,實例化的對象。對象實例化過程中,會做載入webapp,在特定端口等待客戶連接等工作。?

從server.xml到對象的映射是通過commons-digester.jar包完成的。這個包的一個主要功能就是映射xml到java對象。

public class Catalina extends Embedded {

? ? protected String configFile = "conf/server.xml";

? ? /**

? ? ?* The application main program.

? ? ?* @param args Command line arguments

? ? ?*/

? ? public static void main(String args[]) {

? ? ? ? (new Catalina()).process(args);

? ? }

? ? /**

? ? ?* The instance main program.

? ? ?* @param args Command line arguments

? ? ?*/

? ? public void process(String args[]) {

? ? ? ? load(args);

? ? ? ? start();

? ? }

? ? /**

? ? ?* Start a new server instance.

? ? ?*/

? ? public void start() {

? ? ? ? ? ? ? ? ((Lifecycle) getServer()).start();

? ? }

? ? ? ? protected Digester createStartDigester() {

? ? ? ? digester.addObjectCreate("Server",

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"org.apache.catalina.core.StandardServer",

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?"className");

? ? ? ? digester.addSetProperties("Server");

? ? ? ? digester.addSetNext("Server",

? ? ? ? ? ? ? ? ? ? ? ? ? ? "setServer",

? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.apache.catalina.Server");

?

? ? ? ? digester.addSetNext("Server/GlobalNamingResources",

? ? ? ? ? ? ? ? ? ? ? ? ? ? "setGlobalNamingResources",

? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.apache.catalina.deploy.NamingResources");

?

? ? ? ? digester.addSetNext("Server/Listener",

? ? ? ? ? ? ? ? ? ? ? ? ? ? "addLifecycleListener",

? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.apache.catalina.LifecycleListener");

?

? ? ? ? digester.addSetNext("Server/Service",

? ? ? ? ? ? ? ? ? ? ? ? ? ? "addService",

? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.apache.catalina.Service");

?

? ? ? ? digester.addSetNext("Server/Service/Listener",

? ? ? ? ? ? ? ? ? ? ? ? ? ? "addLifecycleListener",

? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.apache.catalina.LifecycleListener");

?

? ? ? ? digester.addSetNext("Server/Service/Executor",

? ? ? ? ? ? ? ? ? ? ? ? ? ? "addExecutor",

? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.apache.catalina.Executor");

?

? ? ? ? digester.addSetNext("Server/Service/Connector",

? ? ? ? ? ? ? ? ? ? ? ? ? ? "addConnector",

? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.apache.catalina.connector.Connector");

?

? ? ? ? digester.addSetNext("Server/Service/Connector/Listener",

? ? ? ? ? ? ? ? ? ? ? ? ? ? "addLifecycleListener",

? ? ? ? ? ? ? ? ? ? ? ? ? ? "org.apache.catalina.LifecycleListener");

? ? }

}

?

//available for use(but not required) when deploying and starting Catalina. ? ? ? ?

public final class StandardServer implements Lifecycle, Server, MBeanRegistration{?

? ? public StandardServer() {

? ? ? ? ServerFactory.setServer(this);

? ? ? ? globalNamingResources = new NamingResources();

? ? ? ? globalNamingResources.setContainer(this);

? ? ? ? if (isUseNaming()) {

? ? ? ? ? ? if (namingContextListener == null) {

? ? ? ? ? ? ? ? namingContextListener = new NamingContextListener();

? ? ? ? ? ? ? ? addLifecycleListener(namingContextListener);

? ? ? ? ? ? }

? ? ? ? }

? ? }

? ? private javax.naming.Context globalNamingContext = null;

? ? private NamingResources globalNamingResources = null;

? ? private NamingContextListener namingContextListener = null;

? ? /**

? ? ?* The port number on which we wait for shutdown commands.

? ? ?*/

? ? private int port = 8005;

? ? awaitSocket = new ServerSocket(port, 1, InetAddress.getByName("localhost"));

} ? ? ? ?

?

?

public class Connector implements Lifecycle, MBeanRegistration{

? ? protected Service service = null;

? ? /**

? ? ?* The Container used for processing requests received by this Connector.

? ? ?*/

? ? protected Container container = null;

? ? /**

? ? ?* Use "/" as path for session cookies ?

? ? ?*/

? ? protected boolean emptySessionPath = false;

? ? ? ? /**

? ? ?* The redirect port for non-SSL to SSL redirects.

? ? ?*/

? ? protected int redirectPort = 443;

? ? /**

? ? ?* The request scheme that will be set on all requests received through this connector.

? ? ?*/

? ? protected String scheme = "http";

? ? /**

? ? ?* Maximum size of a POST which will be automatically parsed by the

? ? ?* container. 2MB by default.

? ? ?*/

? ? protected int maxPostSize = 2 * 1024 * 1024;

? ? /**

? ? ?* Maximum size of a POST which will be saved by the container

? ? ?* during authentication可信的. 4kB by default

? ? ?*/

? ? protected int maxSavePostSize = 4 * 1024;

? ? /**

? ? ?* The background thread.

? ? ?*/

? ? protected Thread thread = null;

? ? /**

? ? ?* Coyote Protocol handler class name.

? ? ?* Defaults to the Coyote HTTP/1.1 protocolHandler.

? ? ?*/

? ? protected String protocolHandlerClassName =

? ? ? ? "org.apache.coyote.http11.Http11Protocol";

? ? /**

? ? ?* Coyote protocol handler.

? ? ?*/

? ? protected ProtocolHandler protocolHandler = null;

? ? /**

? ? ?* Coyote adapter.

? ? ?*/

? ? protected Adapter adapter = null;

? ? ?/**

? ? ? * Mapper.

? ? ? */

? ? ?protected Mapper mapper = new Mapper();

? ? ?/**

? ? ? * Mapper listener.

? ? ? */

? ? ?protected MapperListener mapperListener = new MapperListener(mapper, this);

? ? ?/**

? ? ? * URI encoding.

? ? ? */

? ? ?protected String URIEncoding = null;

? ? ?/**

? ? ? * URI encoding as body.

? ? ? */

? ? protected boolean useBodyEncodingForURI = false;

? ? /**

? ? ?* Set the Coyote protocol which will be used by the connector.

? ? ?*/

? ? public void setProtocol(String protocol) {

? ? ? ? if (AprLifecycleListener.isAprAvailable()) {

? ? ? ? ? ? if ("HTTP/1.1".equals(protocol)) {

? ? ? ? ? ? ? ? setProtocolHandlerClassName

? ? ? ? ? ? ? ? ? ? ("org.apache.coyote.http11.Http11AprProtocol");

? ? ? ? ? ? } else if ("AJP/1.3".equals(protocol)) {

? ? ? ? ? ? ? ? setProtocolHandlerClassName

? ? ? ? ? ? ? ? ? ? ("org.apache.coyote.ajp.AjpAprProtocol");

? ? ? ? ? ? } else if (protocol != null) {

? ? ? ? ? ? ? ? setProtocolHandlerClassName(protocol);

? ? ? ? ? ? } else {

? ? ? ? ? ? ? ? setProtocolHandlerClassName

? ? ? ? ? ? ? ? ? ? ("org.apache.coyote.http11.Http11AprProtocol");

? ? ? ? ? ? }

? ? ? ? } else {

? ? ? ? ? ? if ("HTTP/1.1".equals(protocol)) {

? ? ? ? ? ? ? ? setProtocolHandlerClassName

? ? ? ? ? ? ? ? ? ? ("org.apache.coyote.http11.Http11Protocol");

? ? ? ? ? ? } else if ("AJP/1.3".equals(protocol)) {

? ? ? ? ? ? ? ? setProtocolHandlerClassName

? ? ? ? ? ? ? ? ? ? ("org.apache.jk.server.JkCoyoteHandler");

? ? ? ? ? ? } else if (protocol != null) {

? ? ? ? ? ? ? ? setProtocolHandlerClassName(protocol);

? ? ? ? ? ? }

? ? ? ? }

? ? }

?

? ? /**

? ? ?* Create (or allocate) and return a Request object suitable for

? ? ?* specifying the contents of a Request to the responsible Container.

? ? ?org.apache.catalina.connector.Request

? ? ?*/

? ? public Request createRequest() {

? ? ? ? Request request = new Request();

? ? ? ? request.setConnector(this);

? ? ? ? return (request);

? ? }

? ? /**

? ? ?* Create (or allocate) and return a Response object suitable for

? ? ?* receiving the contents of a Response from the responsible Container.

? ? ?*/

? ? public Response createResponse() {

? ? ? ? Response response = new Response();

? ? ? ? response.setConnector(this);

? ? ? ? return (response);

? ? }

? ? // 省略------------------------------------------------------ Lifecycle Methods

? ? // 省略-------------------- JMX registration ?--------------------

? ? /**

? ? ?* Shutdown hook which will perform a clean shutdown of Catalina if needed.

? ? ?*/

? ? protected class CatalinaShutdownHook extends Thread {

? ? ? ? public void run() {

? ? ? ? ? ? try {

? ? ? ? ? ? ? ? if (getServer() != null) {

? ? ? ? ? ? ? ? ? ? Catalina.this.stop();

? ? ? ? ? ? ? ? }

? ? ? ? ? ? } catch (Throwable ex) {

? ? ? ? ? ? ? ? log.error(sm.getString("catalina.shutdownHookFail"), ex);

? ? ? ? ? ? } finally {

? ? ? ? ? ? ? ? // If JULI is used, shut JULI down *after* the server shuts down

? ? ? ? ? ? ? ? // so log messages aren't lost

? ? ? ? ? ? ? ? LogManager logManager = LogManager.getLogManager();

? ? ? ? ? ? ? ? if (logManager instanceof ClassLoaderLogManager) {

? ? ? ? ? ? ? ? ? ? ((ClassLoaderLogManager) logManager).shutdown();

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? }

? ? }

} ? ? ? ??

?

public interface Engine extends Container {

? ? public String getDefaultHost();

? ? public void setDefaultHost(String defaultHost);

? ? public String getJvmRoute();

? ? public void setJvmRoute(String jvmRouteId);

? ? public Service getService();

? ? public void setService(Service service);

} ? ? ? ?

public class StandardEngine extends ContainerBase implements Engine{} ? ? ? ?

?

?

public class StandardHost extends ContainerBase implements Host{

? ? ? ? /**

? ? ?* The set of aliases for this Host.

? ? ?*/

? ? ? ? private String[] aliases = new String[0];

? ? private final Object aliasesLock = new Object();

? ? /**

? ? ?* The application root for this Host.

? ? ?*/

? ? private String appBase = "webapps";

? ? /**

? ? ?* The auto deploy flag for this Host.

? ? ?*/

? ? private boolean autoDeploy = true;

? ? /**

? ? ?* The Java class name of the default context configuration class

? ? ?* for deployed web applications.

? ? ?*/

? ? private String configClass =

? ? ? ? "org.apache.catalina.startup.ContextConfig";

? ? /**

? ? ?* The Java class name of the default Context implementation class for

? ? ?* deployed web applications.

? ? ?*/

? ? private String contextClass =

? ? ? ? "org.apache.catalina.core.StandardContext";

? ? /**

? ? ?* Attribute value used to turn on/off XML namespace awarenes.

? ? ?*/

? ? ?private boolean xmlNamespaceAware = false;

? ? ?/**

? ? ? * Track the class loaders for the child web applications so memory leaks漏洞

? ? ? * can be detected.

? ? ? */

? ? ?private Map<ClassLoader, String> childClassLoaders =

? ? ? ? ?new WeakHashMap<ClassLoader, String>();

? ? ?...其他的field省略

} ? ? ? ??

?

/**

?* Standard implementation of the <b>Context</b> interface. ?Each

?* child container must be a Wrapper implementation to process the

?* requests directed to a particular servlet.

?*/

public class StandardContext extends ContainerBase implements Context, Serializable, NotificationEmitter{ ? ? ? ?

? ? ? ? /**

? ? ?* The ServletContext implementation associated with this Context.

? ? ?*/

? ? protected transient ApplicationContext context = null;

? ? /**

? ? ?* Compiler classpath to use.

? ? ?*/

? ? private String compilerClasspath = null;

? ? ?/**

? ? ?* Should we attempt to use cookies for session id communication?

? ? ?*/

? ? private boolean cookies = true;

? ? /**

? ? ?* Should we allow the <code>ServletContext.getContext()</code> method

? ? ?* to access the context of other web applications in this server?

? ? ?*/

? ? private boolean crossContext = false;

? ? /**

? ? ?* The MIME mappings for this web application, keyed by extension.

? ? ?*/

? ? private HashMap mimeMappings = new HashMap();

? ? /**

? ? ?* The servlet mappings for this web application, keyed by

? ? ?* matching pattern.

? ? ?*/

? ? private HashMap servletMappings = new HashMap();

? ? /**

? ? ?* The welcome files for this application.

? ? ?*/

? ? private String welcomeFiles[] = new String[0];

? ? /**

? ? ?* Cache object max size in KB.

? ? ?*/

? ? protected int cacheObjectMaxSize = 512; // 512K

? ? /**

? ? ?* Cache TTL in ms.

? ? ?*/

? ? protected int cacheTTL = 5000;

? ? ?/**

? ? ?* The domain to use for session cookies. <code>null</code> indicates that

? ? ?* the domain is controlled by the application.

? ? ?*/

? ? private String sessionCookieDomain;

? ? /**

? ? ?* The path to use for session cookies. <code>null</code> indicates that

? ? ?* the path is controlled by the application.

? ? ?*/

? ? private String sessionCookiePath;

? ? /**

? ? ?* The name to use for session cookies. <code>null</code> indicates that

? ? ?* the name is controlled by the application.

? ? ?*/

? ? private String sessionCookieName;

} ? ? ? ? ? ?

?

/**

?* Standard implementation of the <b>Wrapper</b> interface that represents

?* an individual servlet definition. ?No child Containers are allowed, and

?* the parent Container must be a Context.

?*/

public interface Wrapper extends Container{}?

public class StandardWrapper extends ContainerBase implemen ts ServletConfig, Wrapper, NotificationEmitter {

? ? ? ? /**

? ? ?* The (single) initialized instance of this servlet.

? ? ?*/

? ? protected Servlet instance = null;

? ? /**

? ? ?* The context-relative URI of the JSP file for this servlet.

? ? ?*/

? ? protected String jspFile = null;

} ? ? ? ?

?

/**

?* Standard implementation of <code>ServletContext</code> that represents

?* a web application's execution environment. ?An instance of this class is

?* associated with each instance of <code>StandardContext</code>.

?*/

public class ApplicationContext implements ServletContext {

? ? /**

? ? ?* The Context instance with which we are associated.

? ? ?*/

? ? private StandardContext context = null;

? ? ? ? /**

? ? ?* Base path.

? ? ?*/

? ? private String basePath = null;

? ? ? ? public String getRealPath(String path) {

? ? ? ? ? ? ? ? File file = new File(basePath, path);

? ? ? ? return (file.getAbsolutePath());

? ? ? ? }

? ? /**

? ? ?* Return a <code>RequestDispatcher</code> instance that acts as a

? ? ?* wrapper for the resource at the given path. ?The path must begin

? ? ?* with a "/" and is interpreted as relative to the current context root.

? ? ?*

? ? ?* @param path The path to the desired resource.

? ? ?*/

? ? public RequestDispatcher getRequestDispatcher(String path) {}

? ? protected StandardContext getContext() {

? ? ? ? return this.context;

? ? }

} ? ? ? ?

?

/**

?* Startup event listener for a <b>Context</b> that configures the properties

?* of that Context, and the associated defined servlets.

?*/

public class ContextConfig implements LifecycleListener {

? ? /**

? ? ?* The Context we are associated with.

? ? ?*/

? ? protected Context context = null;

? ? /**

? ? ?* The default web application's context file location.

? ? ?*/

? ? protected String defaultContextXml = null;

? ? /**

? ? ?* The default web application's deployment descriptor location.

? ? ?*/

? ? protected String defaultWebXml = null;

} ? ? ? ?

?

?

org.apache.catalina.core.ApplicationHttpRequest?

? ? ? ? extends javax.servlet.http.HttpServletRequestWrapper?

? ? ? ? extends javax.servlet.ServletRequestWrapper

?

//作用類似javaBean

public final class org.apache.coyote.Request{

? ? ? ? private int serverPort = -1;

? ? ? ? private UDecoder urlDecoder = new UDecoder();

? ? ? ? private MimeHeaders headers = new MimeHeaders();

? ? ? ? private MessageBytes uriMB = MessageBytes.newInstance(); ? ? ? ?

}

org.apache.catalina.connector.Request implements HttpServletRequest{

? ? ? ? protected org.apache.coyote.Request coyoteRequest

? ? ? ? public InputStream getStream() {

? ? ? ? if (inputStream == null) {

? ? ? ? ? ? inputStream = new CoyoteInputStream(inputBuffer);

? ? ? ? }

? ? ? ? return inputStream;

? ? }

? ? ? ? protected int readPostBody(byte body[], int len)throws IOException {

? ? ? ? ? ? ? ? int inputLen = getStream().read(body, offset, len - offset);

? ? ? ? }

? ? ? ? /**

? ? ?* Return the session associated with this Request, creating one

? ? ?* if necessary and requested.

? ? ?*/

? ? public HttpSession getSession(boolean create) {

? ? ? ? Session session = doGetSession(create);

? ? ? ? if (session != null) {

? ? ? ? ? ? return session.getSession();

? ? ? ? } else {

? ? ? ? ? ? return null;

? ? ? ? }

? ? }

? ? ? ? /**

? ? ?* Change the ID of the session that this request is associated with. There

? ? ?* are several things that may trigger an ID change. These include moving

? ? ?* between nodes in a cluster and session fixation prevention during the

? ? ?* authentication process.

? ? ?*/

? ? public void changeSessionId(String newSessionId) {...}

? ? protected Session doGetSession(boolean create) {

? ? ? ? // Attempt to reuse session id if one was submitted in a cookie

? ? ? ? // Do not reuse the session id if it is from a URL, to prevent possible

? ? ? ? // phishing attacks

? ? ? ? if (connector.getEmptySessionPath()?

? ? ? ? ? ? ? ? && isRequestedSessionIdFromCookie()) {

? ? ? ? ? ? session = manager.createSession(getRequestedSessionId());

? ? ? ? } else {

? ? ? ? ? ? ? ? //createSession最終會調用StandardSession的構造。

? ? ? ? ? ? session = manager.createSession(null);

? ? ? ? }

? ? ? ? // Creating a new session cookie based on that session

? ? ? ? if ((session != null) && (getContext() != null)

? ? ? ? ? ? ? ?&& getContext().getCookies()) {

? ? ? ? ? ? String scName = context.getSessionCookieName();

? ? ? ? ? ? if (scName == null) {

? ? ? ? ? ? ? ? scName = Globals.SESSION_COOKIE_NAME;

? ? ? ? ? ? }

? ? ? ? ? ? Cookie cookie = new Cookie(scName, session.getIdInternal());

? ? ? ? ? ? configureSessionCookie(cookie);

? ? ? ? ? ? //save到瀏覽器內存

? ? ? ? ? ? response.addSessionCookieInternal(cookie, context.getUseHttpOnly());

? ? ? ? }

? ? }

? ? ?/**

? ? ?* Parse accept-language header value.

? ? ?*/

? ? protected void parseLocalesHeader(String value) {...}

? ? public String getParameter(String name) {...}

}

?

Connector通過8080端口連接coyote http1.1,通過8009連接coyote AJP1.3

?

ServerCookie、Cookies與javax.servlet.http.Cookie的聯系?

cookie如何實現的?還有瀏覽器的。如何獲取解析cookie、url重寫過的sessionid ? ? ?

/**

?* ?Server-side cookie representation.

?* ?Allows recycling and uses MessageBytes as low-level

?* ?representation ( and thus the byte-> char conversion can be delayed

?* ?until we know the charset ).

?* ?Tomcat.core uses this recyclable object to represent cookies,

?* ?and the facade will convert it to the external representation.

?*/

public class org.apache.tomcat.util.http.ServerCookie implements Serializable {...} ? ? ? ?

?

/**

?* A collection of cookies - reusable and tuned for server side performance.

?* Based on RFC2965 ( and 2109 )

?*/

public final class org.apache.tomcat.util.http.Cookies {?

? ? ServerCookie scookies[]=new ServerCookie[INITIAL_SIZE];

? ? /** Register a new, unitialized cookie. Cookies are recycled, and

? ? ?* ?most of the time an existing ServerCookie object is returned.

? ? ?* ?The caller can set the name/value and attributes for the cookie

? ? ?*/

? ? public ServerCookie addCookie() {

? ? ? ? if( cookieCount >= scookies.length ?) {

? ? ? ? ? ? ServerCookie scookiesTmp[]=new ServerCookie[2*cookieCount];

? ? ? ? ? ? System.arraycopy( scookies, 0, scookiesTmp, 0, cookieCount);

? ? ? ? ? ? scookies=scookiesTmp;

? ? ? ? }

? ? ? ? ServerCookie c = scookies[cookieCount];

? ? ? ? if( c==null ) {

? ? ? ? ? ? c= new ServerCookie();

? ? ? ? ? ? scookies[cookieCount]=c;

? ? ? ? }

? ? ? ? cookieCount++;

? ? ? ? return c;

? ? }

? ? /** Add all Cookie found in the headers of a request.

? ? ?*/

? ? public ?void processCookies( MimeHeaders headers ) {...

? ? /**

? ? ?* Parses a cookie header after the initial "Cookie:"

? ? ?* [WS][$]token[WS]=[WS](token|QV)[;|,]

? ? ?* RFC 2965

? ? ?* JVK

? ? ?*/

? ? public final void processCookieHeader(byte bytes[], int off, int len){...}

}

?

//為什么要多這個對象StandardSessionFacade?????

public class StandardSessionFacade implements HttpSession {

? ? private HttpSession session = null;

}

/**

?* Standard implementation of the <b>Session</b> interface. ?This object is

?* serializable, so that it can be stored in persistent storage or transferred

?* to a different JVM for distributable session support.

?* If you add fields to this class, you must

?* make sure that you carry them over in the read/writeObject methods so

?* that this class is properly serialized.

?*/

public class StandardSession implements HttpSession, Session, Serializable {

? ? /**

? ? ?* The time this session was created, in milliseconds since midnight,

? ? ?* January 1, 1970 GMT.

? ? ?*/

? ? protected long creationTime = 0L;

? ? /**

? ? ?* Return the <code>HttpSession</code> for which this object

? ? ?* is the facade.

? ? ?*/

? ? protected static HttpSessionContext sessionContext = null;?

? ? protected transient StandardSessionFacade facade = null;

? ? public HttpSession getSession() {

? ? ? ? return (facade);

? ? }

? ? /**

? ? ?* The HTTP session context associated with this session.

? ? ?*/

? ? /**

? ? ?* Inform通知 the listeners about the new session.此類中有多種多個event、listener

? ? ?*/

? ? public void tellNew() {...}

? ? /**

? ? ?* Update the accessed time information for this session. ?This method

? ? ?* should be called by the context when a request comes in for a particular

? ? ?* session, even if the application does not reference it.

? ? ?* 會被invokeHttp11NioProcessor之類的invoke(request, response)調用;

? ? ?*/

? ? public void access() {...}

} ??

?

/**

?* Standard implementation of the <b>Server</b> interface, available for use

?* (but not required) when deploying and starting Catalina.

?*

?* @author Craig R. McClanahan

?* @version $Id: StandardServer.java 1066492 2011-02-02 15:02:49Z kkolinko $

?*/

public final class StandardServer implements Lifecycle, Server, MBeanRegistration {

? ? ? ? awaitSocket = new ServerSocket(port, 1,InetAddress.getByName("localhost"));

} ??

?

好多類中都會創建ServerSocket比如下面這幾個: ? ? ? ? ? ? ? ?

? ? ? ? org\apache\coyote\http11\Http11Protocol.java

? ? ? ? org\apache\jk\common\ChannelNioSocket.java ? ? ? ? ? ? ? ?

? ? ? ? ? ? ? ? ServerSocketChannel ssc = ServerSocketChannel.open();

? ? ? ? org\apache\jk\common\ChannelSocket.java

? ? ? ? ? ? ? ? ?ServerSocket sSocket = new ServerSocket( i, backlog );

? ? ? ? org\apache\tomcat\util\net\JIoEndpoint.java

? ? ? ? ? ? ? ? ? ?serverSocket = serverSocketFactory.createSocket(port, backlog);

? ? ? ? org\apache\tomcat\util\net\NioEndpoint.java ? ? ? ? ? ? ? ?

? ? ? ? ? ? ? ? serverSock = ServerSocketChannel.open();

其實創建一個 session 并不耗什么資源,無非就是一個空的map,就是別往里面塞太多的東西,尤其是在集群環境下,會增加同步的負擔。 ? ? ? ? ? ? ? ? ?

? 在文件《D:\study\src_zip\org\apache\catalina\core\StandardServer.java》中查找:"getInputStream"

? ? ? ? ? ? ? ? ? ? ? ? stream = socket.getInputStream(); ??


總結

以上是生活随笔為你收集整理的(精)tomcat 源码学习的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。