Java基礎27:Servlet實現一對多映射URL

前言:打臉了,前腳剛說過要跟Servlet正式告別。結果最近的面試被問到了同一個Servlet可不可以被映射到多個URL上,也就是如何用一個Servlet實現多個功能。


前置知識:

Servlet容器如何處理請求資源路徑?

  1、這個地址  http://localhost:8080/ttms1.01/indexUI.do   什麼是請求資源路徑? 

    在地址欄中輸入的請求地址中,端口號之後的部分都是請求資源路徑。

    緊跟端口號的是部署到Web服務器上的應用名(appName)

    緊跟應用名的則是具體的應用內的組件路徑。

  2、Web服務器對請求地址的處理過程:

    瀏覽器依據地址中的IP和端口號與Web服務器建立連接,服務器會獲取到請求資源路徑信息。根據端口號後面的應用名找到服務器上對應的應用。默認情況下容器會認爲應用名後面的是一個Servlet,所以回到web.xml文件中所有是否有與該值匹配的<url-pattern>,找到匹配的值之後再按照<servlet-name>完成對應關係的查找,進而找到要執行的Servlet。如果沒有找到匹配的資源服務器就會返回404錯誤。匹配Servlet的規則

      精確匹配 /

      通配符匹配 *

      後綴匹配 *.


1、Servlet能不能一對多映射?

問題:web.xml配置中一個servlet能不能映射多個url-pattern?
(1)同一個Servlet可以被映射到多個URL上,即多個<servlet-mapping>元素的<servlet-name>子元素的設置值可以是同一個Servlet的註冊名。
(2)在Servlet映射到的URL中也可以使用*通配符,但是隻能有兩種固定的格式:一種格式是“*.擴展名”,另一種格式是以正斜槓(/)開頭並以“/*”結尾。

<servlet-mapping>
<servlet-name>AnyName</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>

<servlet-mapping>
<servlet-name>AnyName</servlet-name>
<url-pattern>/action/*</url-pattern>
</servlet-mapping>

下面例子顯示了針對同一Servlet實例的兩個不同 pattern:

一個Servlet 可以接受任何數量url-patterns的requests 。

<servlet-mapping>
<servlet-name>getStatus</servlet-name>
<url-pattern>/status/*</url-pattern>
</servlet-mapping>

<servlet-mapping>
<servlet-name>getStatus</servlet-name>
<url-pattern>/briefStatus/*</url-pattern>
</servlet-mapping>

不同的pattern可以映射到同一個Servlet,但同一個pattern不能映射到不同的Servlet。

2、爲什麼要使用一個Servlet來處理多個請求?

  當瀏覽器發送了一次請求到服務器時,servlet容器會根據請求的url-pattern找到對應的Servlet類,執行對應的doPost或doGet方法,再將響應信息返回給瀏覽器,這種情況下,一個具體的Servlet類只能處理對應的web.xml中配置的url-pattern請求,一個Servlet類,一對配置信息。如果業務擴展,需要三個Servlet來處理請求,就需要再加上兩個具體的Servlet類,兩對配置信息,如果繼續向上擴展,是不是會認爲如此寫法的效率非常低下?並且會浪費更多的資源?

  爲了避免重複的操作(多次編寫配置文件,多次新建具體的Servlet類)影響效率,就衍生出一套簡單的操作來提高效率,一次配置,多次使用;一個Servlet具體類,處理多個請求。

3、如何使用一個Servlet來處理多個請求(將多個servlet合併)?

   a、根據請求的地址,截取其中的具體方法名,然後使用if-else判斷匹配,再執行具體的方法。

  b、根據截取出來的方法名,使用反射機制,來執行具體的方法。

  第一種方案很笨拙,需要不斷的使用if-else來判斷;第二種方法相對來講,靈活的處理了原先需要使用if-else的判斷邏輯,由類根據方法名自主去執行。

 

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