Servlet 如何工作

hahadelphi發表於2021-09-09

我們已經清楚了 Servlet 是如何被載入的、初始化及其體系結構,現在的問題就是它是如何被呼叫的.

使用者從瀏覽器向伺服器發起的一個請求通常會包含如下資訊
port /contextpath/servletpath

  • hostname 和 port:與伺服器建立 TCP 連線

  • URL:選擇在伺服器中哪個子容器服務使用者的請求

伺服器是如何根據這個 URL 到達正確的 Servlet 容器中的呢?

  • 在 Tomcat7 中這件事很容易解決,因為這種對映工作有專門的一個類來完成    org.apache.tomcat.util.http.mapper.
    該類儲存了 Tomcat 的 Container 容器中所有子容器的資訊.
    org.apache.catalina.connector.Request 類進入 Container 容器之前,mapper 會根據這次請求的 hostnanecontextpathhostcontext 容器設定到 RequestmappingData 屬性中,如下圖所示.
    所以當 Request進入 Container 容器之前,它要訪問哪個子容器就已經確定了.

    圖片描述

    Request 的 Mapper 類關係圖

可能你有疑問,mapper 中怎麼會有容器的完整關係?
這要回到http://upload-images.jianshu.io/upload_images/4685968-f4c4cc6126fe8e14.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/700中 第 19 步 MapperListener 類的初始化過程,下面是其的init 方法程式碼

 public void init() { 
        findDefaultHost(); 
        Engine engine = (Engine) connector.getService().getContainer(); 
        engine.addContainerListener(this); 
        Container[] conHosts = engine.findChildren(); 
        for (Container conHost : conHosts) { 
            Host host = (Host) conHost; 
            if (!LifecycleState.NEW.equals(host.getState())) { 
                host.addLifecycleListener(this); 
                registerHost(host); 
            } 
        } 
 }

這段程式碼的作用就是將 MapperListener 作為一個監聽者加到整個 Container 容器的每個子容器中.
如此,任何一個容器發生變化,MapperListener 都將會被通知到,相應的儲存容器關係的 MapperListener 的 mapper 屬性也會被修改.
在for 迴圈中就是將 host 及下面的子容器註冊到 mapper 中.


圖片描述

Request 在容器中的路由圖

上圖描述了一次 Request 請求如何達到最終的 Wrapper 容器.
我們現在知道了請求是如何達到正確的 Wrapper 容器,但在請求到達最終的 Servlet 前還要完成一些步驟,必須要執行 Filter 鏈以及通知你在 web.xml 中定義的 listener.

接下來就要執行 Servlet 的 service 方法了,通常我們自定義的 servlet 並不直接實現 javax.servlet.servlet 介面,而是去繼承更簡單的 HttpServlet 或 GenericServlet,我們可以有選擇的覆蓋相應方法去實現我們要完成的工作.

Servlet 的確已經能夠幫我們完成所有的工作了,但是現在的 web 應用很少有直接將互動的全部頁面用 servlet 來實現,而是採用更加高效的 MVC 框架來實現.
這些 MVC 框架基本的原理都是將所有的請求都對映到一個 Servlet,然後去實現 service 方法,這個方法也就是 MVC 框架的入口.

當 Servlet 從 Servlet 容器中移除時,也就表明該 Servlet 的生命週期結束,這時 Servlet 的 destroy 方法將被呼叫,善後.



作者:芥末無疆sss
連結:
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2471/viewspace-2816416/,如需轉載,請註明出處,否則將追究法律責任。

相關文章