1. 程式人生 > >Servlet規範之URL對映

Servlet規範之URL對映

對映請求到Servlet

                        |-- Context Path --|-- Servlet Path -|--Path Info--|
http://www.myserver.com     /mywebapp        /helloServlet      /hello
                        |-------- Request URI  ----------------------------|

引導servlet服務請求的請求路徑由許多重要部分組成。以下元素從請求URI路徑得到,並通過request物件公開:
- Context Path:與ServletContext相關聯的路徑字首是這個servlet的一部分。如果這個上下文是基於Web伺服器的URL名稱空間基礎上的“預設”上下文,那麼這個路徑將是一個空字串。否則,如果上下文不是基於伺服器的名稱空間,那麼這個路徑以/字元開始,但不以/字元結束。
- Servlet Path:路徑部分直接與啟用請求的對映對應。這個路徑以“/”字元開頭,如果請求與“/ *”或“”模式匹配,在這種情況下,它是一個空字串。
- PathInfo:請求路徑的一部分,不屬於Context Path或Servlet Path。如果沒有額外的路徑,它要麼是null,要麼是以’/’開頭的字串。
使用HttpServletRequest介面中的下面方法來訪問這些資訊:
- getContextPath
- getServletPath
- getPathInfo
重要的是要注意,除了請求URI和路徑部分的URL編碼差異外,下面的等式永遠為真:
requestURI = contextPath + servletPath + pathInfo

在web.xml中設定下述的Servlet對映規則

Context Path /catalog Servlet
Servlet Mapping Pattern: /lawn/* LawnServlet
Servlet Mapping Pattern: /garden/* GardenServlet
Servlet Mapping Pattern: *.jsp JSPServlet

得到的結果為

請求路徑 ContextPath ServletPath PathInfo
/catalog/lawn/index.html /catalog /lawn /index.html
/catalog/garden/implements/ /catalog /garden /implements/
/catalog/help/feedback.jsp /catalog /help/feedback.jsp null

servlet容器的url-pattern對映規範

在web應用部署描述符中,以下語法用於定義對映:
- 以‘/’字元開始、以‘/*’字尾結尾的字串用於路徑匹配
- 以‘*.’開始的字串用於副檔名對映
- 只包含“/”字元的字串用於default servlet對映。
- 其他字串僅用於精確匹配。

如果一個url-pattern設定的對映即屬於路徑對映,也屬於擴充套件對映(如:/*.action),導致容器無法判斷,那麼部署將報錯。

default Servlet(預設Servlet)詳解

  • web.xml中如果某個Servlet的對映路徑僅僅為一個正斜槓(/),那麼這個Servlet就成為當前Web應用程式的預設Servlet。
  • 凡是在web.xml檔案中找不到匹配的<servlet-mapping>元素的URL,它們的訪問請求都將交給預設Servlet處理,也就是說,預設Servlet用於處理所有其他Servlet都不處理的訪問請求。
  • 如果在web.xml中未設定一個default Servlet的時候,容器會設定一個容器自帶的Servlet。

    • tomcat容器中會預設註冊了一個名稱為org.apache.catalina.servlets.DefaultServlet的Servlet
    • 當訪問Tomcat伺服器中的某個靜態HTML檔案和圖片時,實際上是在訪問這個預設Servlet,由DefaultServlet類尋找,當尋找到了請求的html或圖片時,則返回資源,如果沒有尋找到則報出404錯誤。

servlet容器對url的匹配過程

在收到客戶端請求時,web容器確定轉發到哪一個Web應用。選擇的Web應用必須具有最長的上下文路徑匹配請求URL的開始。當對映到Servlet時,URL匹配的一部分是上下文。
Web容器接下來必須用下面描述的路徑匹配步驟找出servlet來處理請求。
用於對映到Servlet的路徑是請求物件的請求URL減去上下文和路徑引數部分。下面的URL路徑對映規則按順序使用。使用第一個匹配成功的且不會進一步嘗試匹配:
- 容器將嘗試找到一個請求路徑到servlet路徑的精確路徑匹配。成功匹配則選擇該servlet。
- 容器將遞迴地嘗試最長路徑匹配。這是通過一次一個目錄的遍歷路徑樹完成的,使用‘/’字元作為路徑分隔符。最長匹配確定選擇的servlet。
- 如果URL最後一部分包含一個副檔名(如 .jsp),servlet容器嘗試擴充套件匹配,將檢視匹配為副檔名處理請求的Servlet。副檔名定義在最後一部分的最後一個‘.’字元之後。
- 如果前三個規則都沒有產生一個servlet匹配,容器將試圖為請求資源提供相關的內容。如果應用中定義了一個“default”servlet,它將被使用。許多容器提供了一種隱式的default servlet用於提供內容。

示例對映集合

Path Pattern Servlet 匹配模式
/foo/bar/* servlet1 最長路徑匹配
/baz/* servlet2 最長路徑匹配
/catalog servlet3 精確路徑匹配
*.bop servlet4 擴充套件匹配

注意,精確路徑匹配是全字串匹配,最長路徑匹配是帶正則表示式的字串匹配。
將產生以下結果:

Incoming Path Servlet Handling Request
/foo/bar/index.html servlet1
/foo/bar/index.bop servlet1
/baz servlet2
/baz/index.html servlet2
/catalog servlet3
/catalog/index.html “default” servlet
/catalog/racecar.bop servlet4
/index.bop servlet4

注意,在/catalog/index.html和/catalog/racecar.bop的情況下,不使用對映到“/catalog”的servlet,因為不是精確匹配的。