什麼是 Servlet?——Java Web 開發的核心技術

Published February 16, 2025 by 徐培鈞
程式語言

在現代 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 的處理流程大致如下:

  1. 客戶端發送請求(例如 GET /user?id=123)。
  2. Web 伺服器(如 Nginx)收到請求:若是靜態資源(HTML、CSS、圖片),直接回應;若是動態請求,則將它轉交給應用伺服器(如 Tomcat)。
  3. 應用伺服器比對請求,找到對應的 Servlet,並呼叫 doGet()doPost() 方法,進行商業邏輯處理後產生回應(HTML 或 JSON)。
  4. 應用伺服器將結果回傳給 Web 伺服器
  5. 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。

以下對比表可以幫助理解:

Python 技術WSGI / ASGI
角色規範 Web 應用與伺服器溝通的方式
Python 技術Django / Flask
角色Web 框架,提供 MVC、路由及其他開發功能
Python 技術Gunicorn / Uvicorn
角色負責執行 Web 應用的伺服器
Python 技術Apache / Nginx
角色靜態資源伺服器,同時可做反向代理

舉例來說,Django 內部使用 WSGI 與伺服器(如 Gunicorn、Uvicorn)溝通,就像 Java Web 應用透過 Servlet 與 Tomcat 進行互動一樣。

只是 Python 社群較少強調「規範」,而是以框架和工具為主。


Servlet 的運作原理

簡單來說,Servlet 就是 Java Web 開發中負責處理 使用者請求(Request)並回應結果的程式。

當我們在瀏覽器輸入網址並送出請求時,Servlet 會負責接收這個請求、處理資料,最後把結果傳回給使用者。

但 Servlet 本身不會單獨運作,它需要靠 Servlet 容器(Servlet Container) 來管理它的生命週期,包括:

  • 什麼時候建立它
  • 何時處理請求
  • 何時該結束並釋放資源

讓我們用更直覺的方式來看看 Servlet 是怎麼運作的。


Servlet 的生命週期

Servlet 的運作可以拆成 三大階段

  1. 初始化(載入 & 準備好)
  2. 處理請求(服務用戶端)
  3. 銷毀(關閉 & 釋放資源)

這三個階段就像一個服務生的工作流程:

  1. 上班報到(初始化) → 穿上制服、準備好工作
  2. 服務客人(處理請求) → 根據客人需求上菜、點餐
  3. 下班(銷毀) → 收拾桌面、關燈、回家

現在我們來細看每個階段到底發生了什麼。

Servlet 的初始化

這個階段就是 Servlet「上班報到」的過程

什麼時候 Servlet 會被載入?

  • 伺服器啟動時(如果設定 loadOnStartup=1
  • 第一次有請求進來時(如果沒有設定特別載入時機)

發生了什麼事?

  1. Servlet 容器讀取 Servlet 的類別(就像店長確認這個服務生是誰)
  2. 建立 Servlet 物件(相當於這個服務生正式上班)
  3. 呼叫 init() 方法,讓它準備好(換上制服、確認點菜單)

這時候 Servlet 已經「就位」,隨時等著處理請求。

🔹 重點

  • init() 只會執行 一次,不會每次請求都重新初始化。
  • 通常 init() 會做一些初始設定,比如:
    • 連接資料庫
    • 讀取設定檔
    • 準備一些共用的資源

處理用戶請求(Service 方法)

當有使用者發送請求(例如瀏覽器輸入網址並按 Enter),Servlet 就開始真正「工作」了!

發生了什麼事?

  1. Servlet 容器發現有請求進來
  2. 它會呼叫 service() 方法來處理請求
  3. service() 會根據請求的類型(GET、POST 等)決定要執行 doGet() 還是 doPost()
  4. doGet()doPost() 裡面是開發者寫的邏輯,例如:
    • 查詢資料庫
    • 計算結果
    • 產生 HTML、JSON 回應
  5. 最後,Servlet 透過 response 把結果傳回給使用者

舉個例子

  1. 你在瀏覽器輸入 www.example.com/products
  2. 這個請求被 Servlet 接收到,並呼叫 doGet()
  3. doGet() 可能去資料庫查詢所有產品資訊
  4. 查詢結果會被轉成 HTML 或 JSON,然後回傳給瀏覽器
  5. 你就會看到產品列表的網頁

🔹 重點

  • 每次請求都會呼叫 service(),但 init() 只會執行一次。
  • doGet()doPost() 會根據請求類型來執行不同的邏輯。
  • Servlet 預設是多執行緒 的,也就是說多個使用者同時發送請求時,它會用不同的執行緒來處理,開發時要注意共用資源的安全性

銷毀(釋放資源,結束工作)

當伺服器準備關閉,或是有新的版本部署時,Servlet 需要「下班」,這時候會進入銷毀階段。

發生了什麼事?

  1. 容器會呼叫 destroy() 方法,通知 Servlet 要被移除
  2. destroy() 裡,我們可以釋放一些不再需要的資源,比如:
    • 關閉資料庫連線
    • 清除快取或暫存
    • 寫入日誌記錄
  3. destroy() 執行完後,Servlet 物件就會被刪除,正式「下班」。

🔹 重點

  • destroy() 只會被呼叫一次,當 Servlet 被移除時才會執行。
  • 這裡是做「收尾工作」的好地方,例如關閉資料庫連線或釋放記憶體。

完整流程總結

可以把 Servlet 的生命週期想像成一個服務生的上班流程:

  1. 伺服器啟動(Servlet 載入)
    • 讀取 Servlet 類
    • 建立物件
    • 執行 init()
    • 準備好開始工作
  2. 處理用戶請求
    • service() 方法判斷請求類型(GET/POST)
    • 執行 doGet()doPost()
    • 回應結果給使用者
  3. 伺服器關閉(Servlet 銷毀)
    • 執行 destroy()
    • 釋放資源
    • 移除 Servlet

這樣的流程讓 Servlet 在 Web 應用中可以 高效運作,而開發者只需要專注在 doGet() / doPost() 等方法裡面處理業務邏輯。

為什麼要了解 Servlet 的生命週期?

  1. 避免重複初始化
    • 如果要連接資料庫,應該在 init() 內做,而不是每次請求時重新連線。
  2. 正確釋放資源
    • destroy() 內關閉連線、釋放記憶體,避免記憶體洩漏。
  3. 提升效率
    • 瞭解 service() 如何運作,讓請求處理更順暢,減少不必要的運算。
  4. 確保執行緒安全
    • Servlet 是多執行緒的,所以要小心處理共用資源,避免多個請求同時修改同一個變數導致錯誤。

Servlet 的優勢與應用

Servlet 的優勢

  1. 高效能:Servlet 在伺服器端執行,比 CGI(Common Gateway Interface)等傳統技術更高效。
  2. 可擴展性強:支援 Java EE 技術,如 JSP、Spring MVC,便於擴展。
  3. 安全性高:支援用戶驗證、加密等安全機制。
  4. 跨平台性:基於 Java,適用於各種作業系統和伺服器。

Servlet 的應用場景

  • 企業級 Web 應用(如銀行、電商網站)
  • 後端 API 服務(透過 JSON 或 XML 提供數據)
  • 用戶驗證與 Session 管理
  • MVC 模式的控制層(Controller)

總結

Servlet 是 Java Web 開發的重要技術,負責處理 HTTP 請求並產生動態內容。

透過 Servlet,開發者可以構建高效、安全、可擴展的 Web 應用程式。

在現代開發中,Servlet 雖然常與 JSP、Spring 等框架結合使用,但其核心概念依然是 Web 應用的基石。如果你想深入了解 Java Web 技術,掌握 Servlet 是不可或缺的第一步。

希望這篇文章能幫助你理解 Servlet 的基礎概念與實作方式! 🚀