在 web.xml 文件中,一個(gè) <servlert-mapping>元素用于映射一個(gè) Servlet 的對(duì)外訪問(wèn)路徑,該路徑也稱為虛擬路徑。例如,在《第一個(gè)Servlet程序》教程中,TestServlet01 所映射的虛擬路徑為“/TestServlet01”。
創(chuàng)建好的 Servlet 只有映射成虛擬路徑,客戶端才能對(duì)其進(jìn)行訪問(wèn)。但是在映射 Servlet 時(shí),還有內(nèi)容需要學(xué)習(xí),如 Servlet 的多重映射、在映射路徑中使用通配符、配置默認(rèn)的 Servlet 等。本節(jié)將對(duì)這些內(nèi)容進(jìn)行講解。
Servlet 的多重映射指同一個(gè) Servlet 可以被映射成多條虛擬路徑。也就是說(shuō),客戶端可以通過(guò)多條路徑實(shí)現(xiàn)對(duì)同一個(gè) Servlet 的訪問(wèn)。Servlet 多重映射的實(shí)現(xiàn)方式有以下兩種。
以《第一個(gè)Servlet程序》教程中的 TestServlet01 為例,在 web.xml 文件中的 <servlet-mapping>元素下,增加一個(gè) <servlet-mapping>元素配置,其增加后的代碼如下所示:
<servlet-mapping>
<!-- 映射為T(mén)est01 -->
<servlet-name>TestServlet01</servlet-name>
<url-pattern>/Test01</url-pattern>
</servlet-mapping>
重啟 Tomcat 服務(wù)器,在瀏覽器的地址欄中輸入地址 http://localhost:8080/servletDemo01/TestServlet01 訪問(wèn) TestServlet01,瀏覽器的顯示結(jié)果如圖 1 所示。

圖 1 運(yùn)行結(jié)果
在瀏覽器的地址欄中輸入地址 http://localhost:8080/servletDemo01/Test01 訪問(wèn) TestServlet01,瀏覽器顯示的結(jié)果如圖 2 所示。

圖 2 運(yùn)行結(jié)果
通過(guò)圖 1 和圖 2 的比較,發(fā)現(xiàn)使用兩個(gè) URL 地址都可以正常訪問(wèn) TestServlet01。由此可見(jiàn),通過(guò)配置多個(gè) <servlet-mapping> 元素可以實(shí)現(xiàn) Servlet 的多重映射。
同樣以 TestServlet01 為例,在 web.xml 文件中對(duì) TestServlet01 的<servlet-mapping> 元素進(jìn)行修改,在該元素中配置多個(gè) <url-pattern>,修改后的代碼如下所示:
<servlet-mapping>
<!-- 映射為T(mén)estServlet01和Test02 -->
<servlet-name>TestServlet01</servlet-name>
<url-pattern>/TestServlet01</url-pattern>
<url-pattern>/Test02</url-pattern>
</servlet-mapping>
重啟 Tomcat 服務(wù)器,在瀏覽器的地址欄中輸入地址 http://localhost:8080/servletDemo01/TestServlet01 訪問(wèn) TestServlet01,瀏覽器的顯示結(jié)果如圖 3 所示。

圖 3 運(yùn)行結(jié)果
在瀏覽器的地址欄中輸入地址 http://localhost:8080/servletDemo01/Test02 訪問(wèn) TestServlet01,瀏覽器的顯示結(jié)果如圖 4 所示。

圖 4 運(yùn)行結(jié)果
通過(guò)圖 3 和圖 4 的比較,發(fā)現(xiàn)使用兩個(gè) URL 地址也可以正常訪問(wèn) TestServlet01。由此可見(jiàn),在一個(gè) <servlet-mapping>元素下配置多個(gè) <url-pattern>子元素同樣可以實(shí)現(xiàn) Servlet 的多重映射。
在實(shí)際開(kāi)發(fā)過(guò)程中,開(kāi)發(fā)者有時(shí)會(huì)希望某個(gè)目錄下的所有路徑都可以訪問(wèn)同一個(gè) Servlet,這時(shí),可以在 Servlet 映射的路徑中使用通配符*。通配符的格式有兩種,具體如下。
• 格式為“*.擴(kuò)展名”,例如 *.do 匹配以 .do 結(jié)尾的所有 URL 地址。
• 格式為 /*,例如 /abc/* 匹配以 /abc 開(kāi)始的所有 URL 地址。
需要注意的是,這兩種通配符的格式不能混合使用,例如,/abc/*.do 是不合法的映射路徑。另外,當(dāng)客戶端訪問(wèn)一個(gè) Servlet 時(shí),如果請(qǐng)求的 URL 地址能夠匹配多條虛擬路徑,那么 Tomcat 將采取最具體匹配原則查找與請(qǐng)求 URL 最接近的虛擬映射路徑。例如,對(duì)于如下所示的一些映射關(guān)系:
/abc/* 映射到 Servlet1
/* 映射到 Servlet2
/abc 映射到 Servlet3
*.do 映射到 Servlet4
• 當(dāng)請(qǐng)求 URL 為 /abc/a.html,/abc/* 和 /* 都可以匹配這個(gè) URL,Tomcat 會(huì)調(diào)用 Servlet1。
• 當(dāng)請(qǐng)求 URL 為 /abc、/*、/abc/* 和 /abc 都可以匹配這個(gè) URL,Tomcat 會(huì)調(diào)用 Servlet3。
• 當(dāng)請(qǐng)求 URL 為 /abc/a.do、/*、*.do 和 /abc/* 都可以匹配這個(gè) URL,Tomcat 會(huì)調(diào)用 Servlet1。
• 當(dāng)請(qǐng)求 URL 為 /a.do,/* 和 *.do 都可以匹配這個(gè) URL,Tomcat 會(huì)調(diào)用 Servlet2。
• 當(dāng)請(qǐng)求 URL 為 /xxx/yyy/a.do,*.do 和 /* 都可以匹配這個(gè) URL,Tomcat 會(huì)調(diào)用 Servlet2。
如果某個(gè) Servlet 的映射路徑僅僅是一個(gè)正斜線(/),那么這個(gè) Servlet 就是當(dāng)前 Web 應(yīng)用的默認(rèn) Servlet。Servlet 服務(wù)器在接收到訪問(wèn)請(qǐng)求時(shí),如果在 web.xml 文件中找不到匹配的 <servlet-mapping> 元素的 URL,則會(huì)將訪問(wèn)請(qǐng)求交給默認(rèn) Servlet 處理,也就是說(shuō),默認(rèn) Servlet 用于處理其他 Servlet 都不處理的訪問(wèn)請(qǐng)求。
下面對(duì)《第一個(gè)Servlet程序》教程中的web.xml文件進(jìn)行修改,將其設(shè)置為默認(rèn)的 Servlet,具體如下:
<servlet>
<servlet-name>TestServlet01</servlet-name>
<servlet-class>com.mengma.servlet.TestServlet01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>TestServlet01</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
啟動(dòng) Tomcat 服務(wù)器,在瀏覽器的地址欄中輸入任意地址,如 http://localhost:8080/servletDemo01/abcde,瀏覽器的顯示結(jié)果如圖 5 所示。

圖 5 運(yùn)行結(jié)果
從圖 5 中可以看出,當(dāng) URL 地址和 TestServlet01 的虛擬路徑不匹配時(shí),瀏覽器仍然可以正常訪問(wèn) TestServlet01。
需要注意的是,在 Tomcat 安裝目錄下的 web.xml 文件中也配置了一個(gè)默認(rèn)的 Servlet,配置信息如下所示:
<servlet>
<servlet-name>default</servlet-name>
<serlet-class>org.apache.catalina.servlets.DefaultServlet</serlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
在上面的配置信息中,org.apache.catalina.servlets.DefaultServlet 被設(shè)置為默認(rèn)的 Servlet,它對(duì) Tomcat 服務(wù)器上所有的 Web 應(yīng)用都起作用。
當(dāng) Tomcat 服務(wù)器中的某個(gè) Web 應(yīng)用沒(méi)有默認(rèn) Servlet 時(shí),都會(huì)將 DefaultServlet 作為默認(rèn)的 Servlet。當(dāng)客戶端訪問(wèn) Tomcat 服務(wù)器中的某個(gè)靜態(tài) HTML 文件時(shí),DefaultServlet 會(huì)判斷 HTML 是否存在,如果存在,則會(huì)將數(shù)據(jù)以流的形式回送給客戶端,否則會(huì)報(bào)告 404 錯(cuò)誤。