TOMCAT原理以及處理HTTP請求的過程、ContextPath ServletPath

一、TOMCAT

1 - Tomcat Server的組成部分 

Tomcat服務器是由一系列可配置的組件構成的,其中核心組件是Catalina Servlet容器,它是所有其他Tomcat組件的頂層容器。Tomcat各組件之間的層次關係如圖1-20所示。
-Server
---Service
------Connector
------Engine
---------Context


圖1-20  Tomcat組件之間的層次結構

我們下面簡單介紹一下各組件在Tomcat服務器中的作用。

(1)Server
Server表示整個的Catalina Servlet容器。Tomcat提供了Server接口的一個默認實現,這通常不需要用戶自己去實現。在Server容器中,可以包含一個或多個Service組件。

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類 
如果找到,則執行該類,獲得請求的迴應,並返回 


假設來自客戶的請求爲: 
http://localhost:8080/wsota/wsota_index.jsp 

1) 請求被髮送到本機端口8080,被在那裏偵聽的Coyote HTTP/1.1 Connector獲得 

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

 

二、Context Path、Servlet Path、Path info

                        |-- Context Path --|-- Servlet Path -|--Path Info--|

http://www.myserver.com     /mywebapp        /helloServlet      /hello

                        |-------- Request URI  ----------------------------|

Remember the following three points:
1. Request URI = context path + servlet path + path info.
2. Context paths and servlet paths start with a / but do not end with it.
3. HttpServletRequest provides three methods getContextPath(),
    getServletPath() and getPathInfo() to retrieve the context path,
    the servlet path, and the path info, respectively, associated with a request.


Identifying the servlet path 
To match a request URI with a servlet, the servlet container follows a simple algorithm.
Once it identifies the context path, if any, it evaluates the remaining part of the
request URI with the servlet mappings specified in the deployment descriptor, in the
following order. If it finds a match at any step, it does not take the next step.

The container tries to match the request URI to a servlet mapping. If it finds a
match, the complete request URI (except the context path) is the servlet path. In
this case, the path info is null.
2 It tries to recursively match the longest path by stepping down the request URI
path tree a directory at a time, using the / character as a path separator, and determining
if there is a match with a servlet. If there is a match, the matching part
of the request URI is the servlet path and the remaining part is the path info.
3 If the last node of the request URI contains an extension (.jsp, for example),
the servlet container tries to match it to a servlet that handles requests for the
specified extension. In this case, the complete request URI is the servlet path
and the path info is null.
4 If the container is still unable to find a match, it will forward the request to the
default servlet. If there is no default servlet, it will send an error message indicating
the servlet was not found.

<servlet-mapping>
    <servlet-name>RedServlet</servlet-name>
    <url-pattern>/red/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>RedServlet</servlet-name>
    <url-pattern>/red/red/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>RedBlueServlet</servlet-name>
    <url-pattern>/red/blue/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>BlueServlet</servlet-name>
    <url-pattern>/blue/</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>GreenServlet</servlet-name>
    <url-pattern>/green</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>ColorServlet</servlet-name>
    <url-pattern>*.col</url-pattern>
</servlet-mapping>


Request URI                Servlet Used            Servlet Path        Path Info 
/colorapp/red                RedServlet              /red                 null
/colorapp/red/               RedServlet              /red                 /
/colorapp/red/aaa            RedServlet              /red                 /aaa
 
/colorapp/red/blue/aa        RedBlueServlet          /red/blue            /aa
/colorapp/red/red/aaa        RedServlet              /red/red             /aaa
/colorapp/aa.col             ColorServlet            /aa.col              null
 
/colorapp/hello/aa.col       ColorServlet            /hello/aa.col        null
/colorapp/red/aa.col         RedServlet              /red                 /aa.col
/colorapp/blue               NONE(Error message)                          
/colorapp/hello/blue/        NONE(Error message)                          
/colorapp/blue/mydir         NONE(Error message)
      
/colorapp/blue/dir/aa.col    ColorServlet            /blue/dir/aa.col     null  
/colorapp/green              GreenServlet            /green               null

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章