Servlet
簡單介紹
基於 java 的語言,運行在 web 服務器或應用程式上的程序。 可以接受瀏覽器發過來的請求並回應,交互作用下,生成動態的 web 內容。
技術演進
CGI
全名 共同閘道介面 (Common Gateway Interface),第一種用來產生動態內容的技術,可以使每個請求產生新 Process。
缺點:
請求數量多,響應時間越久。
每個請求,建立新的 Process,耗費大量資源。

Servlet 的演化

解決 CGI 問題 :
每個請求,對應創建 Thread,而不是 Process。
可移植性,主要使用 java 語言,且有 JVM 管理,不需擔心內存問題。
其 object instance 即永久保存在伺服器記憶體中,能自動維護自己的狀態,並持續保有外部資源(資料庫連線)。

演進 1: GenericServlet 抽象類別
基於 Servlet 引進了 ServletRequest
、ServletResponse
的請求與回應,並繼承了 Servlet
、ServletConfig
介面,在他的幫助下,只需要重寫 service() 方法就好。
一般開發也不常直接實作此抽象類別。
演進 2: HttpServlet 抽象類別繼承了GenericServlet 抽象類別,更方便擴展了 http 的內容
基於 HTTP 服務的一個類別,套件 javax.servlet.http,實作重寫了GenericServlet sevice() 方法,將傳入的 ServletRequest
、ServletResponse
轉換為 HttpServletRequest
、HttpServletResponse
(且正也是他的子類別)。
當 Web Server 收到送往此的 request 時,並根據 request method(GET、POST),伺服器去自動呼叫 doGet()、doPost() 來使用即可。
演進 3: JSP的加入
Servlet 目前為止的缺點,就是必須透過 PrintWriter 撰寫大量的 HTML 結構,因此引入了 JSP。
JSP 是一個純文字檔,servlet container 會自動轉換成一個 servlet 程式,由於本質上也是 servlet,同樣也具備其特性,生命週期、多執行緒、session 等優點。
演進4: Spring > Spring MVC
Spring生命週期
初始之前
當 Servlet Container 收到呼叫某 servlet 對象的請求時,會先檢查是否已經載入到記憶體,若還沒有,則容器會使用 class loader 機制載入該 servlet,接著啟動 servlet 建構子建立新的實體。
ClassLoader 機制初始 init
Servlet Container 啟動後並在請求處理之前,會呼叫 Init 方法,也就是執行 servletConfig
介面的init(),就會建立起一個 servlet 對象,並準備好處理請求的過程所需要具備的工作。
特殊情形 : [ Servlet reloading 重載入 ] 、[ Load on Startup 啟動時載入 ]
服務 service
接著會透過 service 方法去處理所有客戶端的請求。
死亡 destroy
Servlet Container 會在 Servlet 卸載之前,先完成所有等待處理的請求之後,主動去呼叫每個 servlet 對象,並執行 Destroy。
幾個主要對象
ServletConfig
可透過 getServletConfig 取得對象,主要是在初始 init 時創建,可以從此對象取得 servletName、servletContext、初始化參數等等。
ServletContext
每一個 web 項目(war) 都屬於一個 servletContext
,在一個項目中共享、管理項目資源。
Request 請求 / Response 回應
即 web 客戶端傳來的訊息與回覆的內容。
web.xml 部署行為
當服務器中接受到了瀏覽器的請求,解析URL路徑,獲取到Servlet的資源路徑。
尋找web.xml文件,找到
<url-pattern>
標籤,並尋找類別名稱<servlet-class>
。Tomcat將字節碼文件加載進記憶體,並且創建對象,調用其中的方法。
所以:Servlet中的大多數方法均不由我們來創建和使用,均由 servlet container 完成
Servlet 3.0+ 使用註解
servlet 3.0的版本,可以透過註解的方式,而不在需要建立 web.xml 檔案。
@ Annotation 註解@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WebServlet {
String name() default "";
String[] value() default {};
String[] urlPatterns() default {};
int loadOnStartup() default -1;
}
@Target({ElementType.TYPE})
作用範圍為類別上。
@Retention(RetentionPolicy.RUNTIME)
保留在運行時期。
最重要的就是這個String[] urlPatterns() default {};
可以配置一個地址,來對應路徑。
參考資料
https://juejin.im/post/5a9f3ddb5188255585071151 https://zhuanlan.zhihu.com/p/52204820 https://zhuanlan.zhihu.com/p/79679019
Last updated
Was this helpful?