Servlet
Servlet 沒有 main 方法,不能夠獨立的運行,它的運行需要容器的支持,Tomcat 是最常用的 JSP/Servlet 容器。
Servlet 運行在 Servlet 容器中,并由容器管理從創(chuàng)建到銷毀的整個過程。
Servlet 的生命周期
(1) 加載和實例化Servlet 容器裝載和實例化一個 Servlet。創(chuàng)建出該 Servlet 類的一個實例。
(2) 初始化在 Servlet 實例化完成之后,容器負責(zé)調(diào)用該 Servlet 實例的 init() 方法,在處理用戶請求之前,來做一些額外的初始化工作。
(3) 處理請求當(dāng) Servlet 容器接收到一個 Servlet 請求時,便運行與之對應(yīng)的 Servlet 實例的 service() 方法,service() 方法再派遣運行與請求相對應(yīng)的
doXX(doGet,doPost) 方法來處理用戶請求。
(4) 銷毀當(dāng) Servlet 容器決定將一個 Servlet 從服務(wù)器中移除時 ( 如 Servlet 文件被更新 ),便調(diào)用該 Servlet 實例的 destroy() 方法,在銷毀該 Servlet 實例之前,
來做一些其他的工作。
其中,(1)(2)(4) 在 Servlet 的整個生命周期中只會被執(zhí)行一次。
Servlet 的工作原理
結(jié)合右邊給出的流程圖:
當(dāng)客戶端瀏覽器向服務(wù)器請求一個 Servlet 時,服務(wù)器收到該請求后,首先到容器中檢索與請求
匹配的 Servlet 實例是否已經(jīng)存在。若不存在,則 Servlet 容器負責(zé)加載并實例化出該類 Servlet
的一個實例對象,接著容器框架負責(zé)調(diào)用該實例的 init() 方法來對實例做一些初始化工作,然后
Servlet 容器運行該實例的 service() 方法。
若 Servlet 實例已經(jīng)存在,則容器框架直接調(diào)用該實例的 service() 方法。
service() 方法在運行時,自動派遣運行與用戶請求相對應(yīng)的 doXX() 方法來響應(yīng)用戶發(fā)起的請求。
通常,每個 Servlet 類在容器中只存在一個實例,每當(dāng)請求到來時,則分配一條線程來處理該請求。
JSP 工作原理
結(jié)合右邊給出的流程圖:
當(dāng)客戶端瀏覽器向服務(wù)器請求一個 JSP 頁面時,服務(wù)器收到該請求后,首先檢查所請求的這個
JSP 文件內(nèi)容 ( 代碼 ) 是否已經(jīng)被更新,或者是否是 JSP 文件創(chuàng)建后的第一次被訪問,如果是,
那么,這個 JSP 文件就會在服務(wù)器端的 JSP 引擎作用下轉(zhuǎn)化為一個 Servlet 類的 Java 源代碼
文件。緊接著,這個 Servlet 類會在 Java 編譯器的作用下被編譯成一個字節(jié)碼文件,并裝載
到 jvm 解釋執(zhí)行。剩下的就等同于 Servlet 的處理過程了。
如果被請求的 JSP 文件內(nèi)容 ( 代碼 ) 沒有被修改,那么它的處理過程也等同于一個 Servlet 的
處理過程。即直接由服務(wù)器檢索出與之對應(yīng)的 Servlet 實例來處理。
需要注意的是,JSP 文件不是在服務(wù)器啟動的時候轉(zhuǎn)換成 Servlet 類的。而是在被客戶端訪問
的時候才可能發(fā)生轉(zhuǎn)換的 ( 如 JSP 文件內(nèi)容沒有被更新等,就不再發(fā)生 Servlet 轉(zhuǎn)換 )。
就 Tomcat 而言,打開目錄 %Tomcat%/work/%您的工程文件目錄%,然后會看到里面有 3
個子目錄:org/apache/jsp,若沒有這 3 個目錄,說明項目的 JSP 文件還沒有被訪問過,
打開進到 jsp 目錄下,會看到一些 *_jsp.java 和 *_jsp.class 文件,這就是 JSP 文件被轉(zhuǎn)換成
Servlet 類的源文件和字節(jié)碼文件了。
有興趣的話,可以使用瀏覽器訪問服務(wù)器中的 JSP,然后觀察 JSP 轉(zhuǎn)換 Servlet 以及編譯的時機。
Servlet 與 JSP
JSP 本質(zhì)是一個 Servlet,它的運行也需要容器的支持。
在 JSP 和 Servlet 文件中都可以編寫 Java 和 HTML 代碼,不同的是,
Servlet 雖然也可以動態(tài)的生成頁面內(nèi)容,但更加偏向于邏輯的控制。
JSP 最終被轉(zhuǎn)換成 Servlet 在 jvm 中解釋執(zhí)行,在 JSP 中雖然也可以編寫 Java 代碼,但它更加偏向于頁面視圖的展現(xiàn)。
在 MVC 架構(gòu)模式中,就 JSP 和 Servlet 而言,C 通常由 Servlet 充當(dāng),V 通常由 JSP 來充當(dāng)。