前面的話
server.xml可以看作tomcat結構的縮影,讀懂了它對tomcat的設計模型及處理機制也就了解了個大概。總之,讀懂server.xml大有裨益。
文件結構預覽
tomcat之server.xml結構圖
解讀
-
Server元素
- 它表示整個tomcat容器,是tomcat的頂層元素,對應org.apache.catalina.Server接口,默認值為org.apache.catalina.core.StandardServer
- 一個Server表示一個完整的JVM獨立組件 ,可以包含一個或多個Service元
- Server表示的是tomcat的整體抽象
-
Service元素
- 對應org.apache.catalina.Service接口,默認為org.apahce.catalina.core.StandardService
- 一個Service包含一個Engine元素和一個或多個Connector元素
-
Connector元素
- 表示與客戶端實際交互的組件,負責接收客戶端請求及返回響應結果
- AJP連接器:用于將Apache與Tomcat集成在一起,當Apache接收到動態內容請求時,通過在配置中指定的端口號將請求發送給在此端口號上監聽的AJP連接器組件
-
Engine元素
- tomcat的標準獨立引擎,分析請求中的HTTP頭信息,并將請求轉發到適當主機或虛擬主機上
- 默認虛擬主機是localhost
-
Host元素
- 一個Engine元素可以包括一個或多個Host元素
- Host元素定義了一個虛擬主機,包含一個或多個Web應用
-
Context元素
- 一個Context元素代表了一個運行在虛擬主機上的單個web應用
節點解釋.png
tomcat請求處理流程
假設請求為:http://localhost:8080/hxysea/index.jsp
- 請求發送到Tomcat上,被監聽在8080端口的Connector獲得
- Conncetor將請求交給它所在Service的Engine處理,并等待Engine響應
- Engine獲取請求localhost/hxysea/index.jsp,匹配到主機名為locaohost虛擬主機Host,將請求交給此Host
- localhost這個Host獲得請求hxysea/index.jsp,匹配到Conext名為hxysea的Context(如果匹配不到就把該請求交給路徑名為""的Context去處理)
- path="/hxysea"的Context獲得請求/index.jsp,在它的mapping table中尋找對應的servlet
- Context匹配到URL PATTERN為*.jsp的servlet,對應于JspServlet類
- 構造HttpServletRequest對象和HttpServletResponse對象,作為參數調用JspServlet的doGet或doPost方法
- Context把執行完的HttpServletResponse對象返回給Host
- Host把HttpServletResponse對象返回給Engine
- Engine把HttpServletResponse對象返回給Connector
- Connector把HttpServletResponse對象返回給客戶端
一個完整的server.xml
<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener className="org.apache.catalina.core.AprLifecycleListener"
SSLEngine="on" />
<Listener className="org.apache.catalina.core.JasperListener" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources>
<!-- 讀取可編輯的conf/tomcat-users.xml文件,用于tomcat授權用戶 -->
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase" description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<!-- Service是眾多Connector的集合,這些Connector共享一個容器,但是Service不是一個容器,故不能定義Valves這樣的子元素 -->
<Service name="Catalina">
<!-- 一個連接器 Connector表示請求和響應的接入端點,如:HTTP Connector、AJP Connector(配合Apache
HTTP Server,作后端處理) -->
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000" redirectPort="8443" />
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<!-- Engine處理請求,分析HTTP請求頭,將請求傳遞給合適的主機處理 -->
<Engine name="Catalina" defaultHost="localhost">
<!-- 賬號鎖定作用域 -->
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase" />
</Realm>
<Host name="localhost" appBase="webapps" unpackWARs="true"
autoDeploy="true">
<!-- 日志配置 -->
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs" prefix="localhost_access_log." suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
部署問題
- tomcat接收get請求,解決中文亂碼問題,增加useBodyEndingForURI=true配置
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443" useBodyEncodingForURI="true"/>