本文為 Java 常見框架與伺服器 系列文,第 2 篇:
- Web 伺服器與應用伺服器的區別與搭配——打造高效能 Web 架構
- 什麼是 Servlet?——Java Web 開發的核心技術 👈進度
- Tomcat 入門指南:從零開始了解 Java Web 伺服器
- Apache 軟體基金會 (ASF) 完整指南:新手入門必讀
- 新手入門:什麼是 JBoss?完整指南
- 新手指南:什麼是 Red Hat?完整介紹與應用解析
- 新手指南:什麼是 WebLogic?完整介紹與應用解析
- 新手指南:什麼是 WebSphere?完整介紹與應用解析
- Spring 框架新手指南:深入理解 Spring 的核心概念與應用
- Spring MVC 初學者指南:深入了解 Spring 的強大框架
在現代 Web 開發中,動態網頁與伺服器端程式扮演著關鍵角色。
其中,Java Servlet 作為 Java EE(Jakarta EE)技術體系中的核心組件,負責處理客戶端的請求並產生響應。無論是在企業級應用還是小型 Web 專案中,Servlet 都是不可或缺的一部分。
本文將深入介紹 Servlet 的概念、運作方式、優勢以及如何開發與部署一個 Servlet。
Servlet 的基本概念
Servlet 是什麼?
Servlet 是 Java 開發的 伺服器端組件,主要用於處理 HTTP 請求並產生回應。它運行於**Servlet 容器(Servlet Container)**中,例如 Tomcat、Jetty 或 JBoss,能夠動態產生網頁內容,並與資料庫或其他後端服務進行交互。
簡單來說,Servlet 就像是一個能夠回應用戶請求的 Java 類,當用戶透過瀏覽器發送請求(如訪問某個網址或提交表單)時,Servlet 會處理該請求並回應相應的內容(如 HTML、JSON 或 XML)。
Servlet 的作用
Servlet 的主要功能包括:
- 處理 HTTP 請求與回應(如 GET、POST 請求)
- 動態產生 HTML 頁面(例如 JSP、模板引擎配合使用)
- 與資料庫或其他後端服務交互
- 管理用戶 Session 與 Cookie
- 作為 MVC 架構中的控制層(Controller)
Servlet 的運作流程
當用戶端(例如瀏覽器)發送 HTTP 請求時,Servlet 的處理流程大致如下:
- 客戶端發送請求(例如
GET /user?id=123)。 - Web 伺服器(如 Nginx)收到請求:若是靜態資源(HTML、CSS、圖片),直接回應;若是動態請求,則將它轉交給應用伺服器(如 Tomcat)。
- 應用伺服器比對請求,找到對應的 Servlet,並呼叫
doGet()或doPost()方法,進行商業邏輯處理後產生回應(HTML 或 JSON)。 - 應用伺服器將結果回傳給 Web 伺服器。
- Web 伺服器將結果回應給客戶端,瀏覽器隨後顯示網頁或 JSON 等回應內容。
sequenceDiagram
participant Client as 客戶端 (瀏覽器)
participant WebServer as Web 伺服器 (Nginx)
participant AppServer as 應用伺服器 (Tomcat)
participant Servlet as Servlet (doGet/doPost)
Client->>WebServer: 發送請求 (GET /user?id=123)
alt 請求為靜態資源 (HTML, CSS, 圖片)
WebServer-->>Client: 直接回應靜態資源
else 請求為動態內容
WebServer->>AppServer: 轉交請求 (動態請求)
AppServer->>Servlet: 找到對應的 Servlet,執行 doGet()/doPost()
Servlet->>Servlet: 處理商業邏輯 (查詢資料庫、計算結果)
Servlet-->>AppServer: 產生回應 (HTML / JSON)
AppServer-->>WebServer: 回傳結果
WebServer-->>Client: 回應結果 (顯示網頁 / JSON)
end
Servlet 與 Django:不同的 Web 開發思維
對於習慣 Python 的開發者而言,Django 或 Flask 都屬於「框架」的概念,並不需要明確面對像 Servlet 這樣的技術規範。
那麼,Servlet 在 Java 世界扮演的角色,可與 Python 生態系統中的哪些技術相對應呢?
Django 與 Spring MVC 的對應
- Django(Python) ⇄ Spring MVC(Java)
兩者同樣都是 Web 框架,提供 MVC 架構、路由、模板系統等功能。 - Python ⇄ Java
雖然是兩種語言,但都能達成 Web 開發目標,只是生態系統與支援方式各不相同。
Servlet 在 Python 世界的對應:WSGI / ASGI
在 Java 世界,Servlet 為 Web 應用和應用伺服器之間的「橋樑」;而在 Python 世界,類似的角色是 WSGI 或 ASGI。
以下對比表可以幫助理解:
| Java 技術 | Python 技術 | 角色 |
|---|---|---|
| Servlet | WSGI / ASGI | 規範 Web 應用與伺服器溝通的方式 |
| Spring MVC / Struts | Django / Flask | Web 框架,提供 MVC、路由及其他開發功能 |
| Tomcat / WildFly | Gunicorn / Uvicorn | 負責執行 Web 應用的伺服器 |
| Apache / Nginx | Apache / Nginx | 靜態資源伺服器,同時可做反向代理 |
舉例來說,Django 內部使用 WSGI 與伺服器(如 Gunicorn、Uvicorn)溝通,就像 Java Web 應用透過 Servlet 與 Tomcat 進行互動一樣。
只是 Python 社群較少強調「規範」,而是以框架和工具為主。
Servlet 的運作原理
簡單來說,Servlet 就是 Java Web 開發中負責處理 使用者請求(Request)並回應結果的程式。
當我們在瀏覽器輸入網址並送出請求時,Servlet 會負責接收這個請求、處理資料,最後把結果傳回給使用者。
但 Servlet 本身不會單獨運作,它需要靠 Servlet 容器(Servlet Container) 來管理它的生命週期,包括:
- 什麼時候建立它
- 何時處理請求
- 何時該結束並釋放資源
讓我們用更直覺的方式來看看 Servlet 是怎麼運作的。
Servlet 的生命週期
Servlet 的運作可以拆成 三大階段:
- 初始化(載入 & 準備好)
- 處理請求(服務用戶端)
- 銷毀(關閉 & 釋放資源)
這三個階段就像一個服務生的工作流程:
- 上班報到(初始化) → 穿上制服、準備好工作
- 服務客人(處理請求) → 根據客人需求上菜、點餐
- 下班(銷毀) → 收拾桌面、關燈、回家
現在我們來細看每個階段到底發生了什麼。
Servlet 的初始化
這個階段就是 Servlet「上班報到」的過程。
什麼時候 Servlet 會被載入?
- 伺服器啟動時(如果設定
loadOnStartup=1) - 第一次有請求進來時(如果沒有設定特別載入時機)
發生了什麼事?
- Servlet 容器讀取 Servlet 的類別(就像店長確認這個服務生是誰)
- 建立 Servlet 物件(相當於這個服務生正式上班)
- 呼叫
init()方法,讓它準備好(換上制服、確認點菜單)
這時候 Servlet 已經「就位」,隨時等著處理請求。
🔹 重點
init()只會執行 一次,不會每次請求都重新初始化。- 通常
init()會做一些初始設定,比如:- 連接資料庫
- 讀取設定檔
- 準備一些共用的資源
處理用戶請求(Service 方法)
當有使用者發送請求(例如瀏覽器輸入網址並按 Enter),Servlet 就開始真正「工作」了!
發生了什麼事?
- Servlet 容器發現有請求進來
- 它會呼叫
service()方法來處理請求 service()會根據請求的類型(GET、POST 等)決定要執行doGet()還是doPost()doGet()或doPost()裡面是開發者寫的邏輯,例如:- 查詢資料庫
- 計算結果
- 產生 HTML、JSON 回應
- 最後,Servlet 透過
response把結果傳回給使用者
舉個例子
- 你在瀏覽器輸入
www.example.com/products - 這個請求被 Servlet 接收到,並呼叫
doGet() doGet()可能去資料庫查詢所有產品資訊- 查詢結果會被轉成 HTML 或 JSON,然後回傳給瀏覽器
- 你就會看到產品列表的網頁
🔹 重點
- 每次請求都會呼叫
service(),但init()只會執行一次。 doGet()和doPost()會根據請求類型來執行不同的邏輯。- Servlet 預設是多執行緒 的,也就是說多個使用者同時發送請求時,它會用不同的執行緒來處理,開發時要注意共用資源的安全性。
銷毀(釋放資源,結束工作)
當伺服器準備關閉,或是有新的版本部署時,Servlet 需要「下班」,這時候會進入銷毀階段。
發生了什麼事?
- 容器會呼叫
destroy()方法,通知 Servlet 要被移除 - 在
destroy()裡,我們可以釋放一些不再需要的資源,比如:- 關閉資料庫連線
- 清除快取或暫存
- 寫入日誌記錄
destroy()執行完後,Servlet 物件就會被刪除,正式「下班」。
🔹 重點
destroy()只會被呼叫一次,當 Servlet 被移除時才會執行。- 這裡是做「收尾工作」的好地方,例如關閉資料庫連線或釋放記憶體。
完整流程總結
可以把 Servlet 的生命週期想像成一個服務生的上班流程:
- 伺服器啟動(Servlet 載入)
- 讀取 Servlet 類
- 建立物件
- 執行
init() - 準備好開始工作
- 處理用戶請求
service()方法判斷請求類型(GET/POST)- 執行
doGet()或doPost() - 回應結果給使用者
- 伺服器關閉(Servlet 銷毀)
- 執行
destroy() - 釋放資源
- 移除 Servlet
- 執行
這樣的流程讓 Servlet 在 Web 應用中可以 高效運作,而開發者只需要專注在 doGet() / doPost() 等方法裡面處理業務邏輯。
為什麼要了解 Servlet 的生命週期?
- 避免重複初始化
- 如果要連接資料庫,應該在
init()內做,而不是每次請求時重新連線。
- 如果要連接資料庫,應該在
- 正確釋放資源
- 在
destroy()內關閉連線、釋放記憶體,避免記憶體洩漏。
- 在
- 提升效率
- 瞭解
service()如何運作,讓請求處理更順暢,減少不必要的運算。
- 瞭解
- 確保執行緒安全
- Servlet 是多執行緒的,所以要小心處理共用資源,避免多個請求同時修改同一個變數導致錯誤。
Servlet 的優勢與應用
Servlet 的優勢
- 高效能:Servlet 在伺服器端執行,比 CGI(Common Gateway Interface)等傳統技術更高效。
- 可擴展性強:支援 Java EE 技術,如 JSP、Spring MVC,便於擴展。
- 安全性高:支援用戶驗證、加密等安全機制。
- 跨平台性:基於 Java,適用於各種作業系統和伺服器。
Servlet 的應用場景
- 企業級 Web 應用(如銀行、電商網站)
- 後端 API 服務(透過 JSON 或 XML 提供數據)
- 用戶驗證與 Session 管理
- MVC 模式的控制層(Controller)
總結
Servlet 是 Java Web 開發的重要技術,負責處理 HTTP 請求並產生動態內容。
透過 Servlet,開發者可以構建高效、安全、可擴展的 Web 應用程式。
在現代開發中,Servlet 雖然常與 JSP、Spring 等框架結合使用,但其核心概念依然是 Web 應用的基石。如果你想深入了解 Java Web 技術,掌握 Servlet 是不可或缺的第一步。
希望這篇文章能幫助你理解 Servlet 的基礎概念與實作方式! 🚀