JSP 是把 Java 程式碼寫進 HTML 的伺服器端網頁技術:使用者打開網頁時,伺服器先執行 Java,再把算好的 HTML 送到瀏覽器。它在 2000 年代是 Java 網站的標準做法,今天仍撐著大量企業、政府與金融系統的畫面層。這篇文章從「JSP 是什麼」開始,說明它的運作原理、四種基本標籤、EL 與 JSTL 的現代寫法、表單與資料庫範例,最後誠實回答一個常見問題:2026 年還值得學 JSP 嗎?本文屬於《網頁程式語言》系列,前後端技術的全貌請先看〈網頁程式設計入門〉。
一、JSP 是什麼?
JSP(Java Server Pages,現正式名稱為 Jakarta Server Pages)是一種伺服器端網頁技術,讓開發者把 Java 程式碼嵌入 HTML,由伺服器執行後產生動態網頁。檔案副檔名是 .jsp,必須放在支援 Java 的網頁容器(例如 Apache Tomcat)上執行,瀏覽器收到的永遠是處理完的 HTML,看不到任何 Java 原始碼。
JSP 由昇陽(Sun Microsystems)在 1999 年推出,目的是簡化 Servlet 的寫法:Servlet 要用 Java 一行一行 println 拼出 HTML,JSP 則反過來,以 HTML 為主、在需要動態內容的地方插入 Java。2019 年起 Java EE 交由 Eclipse 基金會維護並改名 Jakarta EE,JSP 也跟著改稱 Jakarta Server Pages,程式套件從 javax.servlet.jsp 改為 jakarta.servlet.jsp,這是升級舊專案到 Tomcat 10 以後最常踩到的第一個坑。
二、JSP 怎麼運作?從 .jsp 到 HTML 的四個步驟
JSP 頁面第一次被請求時,容器會把它翻譯成 Servlet 原始碼、編譯成 class,之後每次請求都直接執行這個 class。理解這四步,就能解釋為什麼 JSP 第一次開啟特別慢、以及為什麼修改 .jsp 檔通常不用重啟伺服器。
- 翻譯(Translation):容器內的 JSP 引擎(Tomcat 稱為 Jasper)讀取 .jsp,把 HTML 轉成輸出敘述、把 Java 片段原樣保留,產生一個 Servlet 的 .java 檔。
- 編譯(Compilation):把 .java 編譯成 .class。這兩步只在第一次請求或檔案修改後發生,所以第一位訪客會等比較久。
- 執行(Execution):容器載入 class,呼叫它的服務方法,Java 程式讀取請求參數、查資料庫、組合資料。
- 回應(Response):把組合完成的 HTML 透過 HTTP 回傳給瀏覽器。瀏覽器只看到 HTML,不知道背後是 JSP。
整個流程都發生在網頁伺服器與應用程式伺服器這一端;很多 JSP 部署會用 Apache 或 Nginx 在前面接收請求、把動態頁面轉交 Tomcat 處理,這種分工在〈應用程式伺服器是什麼〉有更完整的說明。
三、JSP 基本語法:四種標籤與指令
JSP 的核心語法只有四種標籤,都以 <% 開頭、%> 結尾,差別在第二個字元。以下範例都能直接放進 Tomcat 的 webapps 目錄執行。
1. 表達式標籤 <%= %>:把值印到網頁上
表達式標籤會把 Java 表達式的結果轉成字串,直接輸出在 HTML 的那個位置,不需要寫分號。
<%@ page contentType="text/html; charset=UTF-8" %>
<!DOCTYPE html>
<html lang="zh-Hant">
<body>
<h2>Hello, JSP!</h2>
現在的時間是:<%= new java.util.Date() %>
</body>
</html>
這段程式每次重新整理都會顯示伺服器當下的日期與時間。第一行的 page 指令宣告輸出編碼是 UTF-8,少了它,中文很容易變成問號。
2. Scriptlet 標籤 <% %>:寫邏輯,不直接輸出
Scriptlet 裡面是一般的 Java 敘述,用來宣告變數、做運算、寫判斷,本身不會輸出任何東西,要顯示結果得搭配表達式標籤或 out.println()。
<%
String name = "王小明";
int age = 25;
%>
姓名:<%= name %><br>
年齡:<%= age %>
畫面會顯示「姓名:王小明」與「年齡:25」。Scriptlet 是最早期、也最容易讓程式碼失控的寫法,第六節會說明現代專案為什麼盡量不用它。
3. 宣告標籤 <%! %>:定義方法與成員變數
宣告標籤裡的內容會變成翻譯後 Servlet 類別的成員,可以在同一頁的其他地方呼叫。
<%!
public String greetUser(String userName) {
return "Hello, " + userName + "!";
}
%>
<h2>歡迎訊息:</h2>
<p><%= greetUser("Alice") %></p>
4. 註解與指令
JSP 註解 <%-- --%> 只留在伺服器,不會出現在送給瀏覽器的 HTML 裡;一般的 HTML 註解 <!-- --> 則會被原樣送出,任何人按右鍵檢視原始碼都看得到。指令標籤 <%@ %> 用來設定整頁的屬性,最常用的有三個:
<%-- 這行註解不會送到瀏覽器 --%> <%@ page contentType="text/html; charset=UTF-8" import="java.util.List" %> <%@ include file="header.jsp" %> <%@ taglib prefix="c" uri="jakarta.tags.core" %>
page:設定編碼、要匯入的 Java 套件、錯誤頁面等。include:把另一個檔案在翻譯階段合併進來,常用於共用的頁首、頁尾。taglib:載入標籤庫,第六節的 JSTL 就靠它。Tomcat 10 以後 uri 用jakarta.tags.core,舊專案的http://java.sun.com/jsp/jstl/core在新版容器會找不到。
四、條件判斷與迴圈
在 Scriptlet 裡可以使用所有標準的 Java 流程控制語法。下面兩段分別示範 if/else 與 for 迴圈,注意 Java 敘述結尾要有分號,這和 HTML 交錯時很容易漏掉。
<%
int age = 20;
if (age >= 18) {
out.println("您已成年");
} else {
out.println("您尚未成年");
}
%>
<%
for (int i = 1; i <= 5; i++) {
out.println("這是第 " + i + " 次迴圈<br>");
}
%>
第一段依年齡輸出不同文字,第二段輸出 1 到 5。out 是 JSP 內建的輸出物件,不用自己宣告;同類的內建物件還有 request、response、session、application,下一節會用到。
五、表單處理與資料庫連線
接收表單靠 request.getParameter(),連資料庫靠 JDBC。先看表單:
<form method="post" action="welcome.jsp">
姓名:<input type="text" name="name"><br>
<input type="submit" value="送出">
</form>
<%
request.setCharacterEncoding("UTF-8");
String name = request.getParameter("name");
if (name != null && !name.isBlank()) {
out.println("歡迎," + name + "!");
}
%>
送出表單後,同一頁會顯示「歡迎,+您輸入的名字」。setCharacterEncoding 那行是處理中文表單的關鍵,漏掉就會出現亂碼。接著是讀取 MySQL 資料表的範例:
<%@ page import="java.sql.*" %>
<%
String url = "jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=UTF-8";
try (Connection conn = DriverManager.getConnection(url, "dbuser", "dbpassword");
PreparedStatement ps = conn.prepareStatement("SELECT id, name FROM users WHERE status = ?")) {
ps.setInt(1, 1);
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
out.println("ID:" + rs.getInt("id") + ",名字:" + rs.getString("name") + "<br>");
}
}
} catch (SQLException e) {
out.println("資料庫連線失敗,請稍後再試。");
}
%>
PreparedStatement 帶參數,不要把使用者輸入直接串進 SQL 字串,這是 OWASP 列為第一優先的 SQL 注入防護;第二,帳號密碼與連線字串不該寫在 .jsp 裡,應放在容器的 DataSource 設定並使用連線池;第三,資料庫邏輯根本不該出現在畫面層,這正是下一節要談的事。範例用 try-with-resources 自動關閉連線,比舊教材裡一長串 finally 手動關閉安全許多。
六、現代寫法:EL 與 JSTL 取代 Scriptlet
2000 年代中期以後的 JSP 專案,幾乎都禁止在頁面裡寫 Scriptlet,改用 EL(Expression Language)取值、JSTL(Standard Tag Library)寫流程。原因很實際:Java 與 HTML 混在同一個檔案裡,設計師不敢動、工程師難測試,一個 500 行的 .jsp 沒有人敢維護。
正確的分工是 MVC:Servlet(或 Spring MVC 的 Controller)負責接收請求、呼叫商業邏輯、把結果放進 request 屬性,然後轉交 JSP;JSP 只負責把資料排成畫面。前面第五節的資料庫範例,改成 MVC 寫法後畫面層會變成這樣:
<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="c" uri="jakarta.tags.core" %>
<h2>會員清單</h2>
<c:if test="${empty users}">
<p>目前沒有資料。</p>
</c:if>
<ul>
<c:forEach var="u" items="${users}">
<li>ID:${u.id},名字:<c:out value="${u.name}"/></li>
</c:forEach>
</ul>
- EL
${...}:讀取 request、session 等範圍裡的物件與屬性,${u.name}會自動呼叫getName(),完全不用寫 Java。 - JSTL
<c:if>、<c:forEach>:用標籤取代 if 與 for,讀起來和 HTML 一致。 <c:out>:輸出時自動把<、>等字元轉義,是防止跨站腳本(XSS)最省力的方法;直接用${u.name}輸出使用者填入的內容則沒有這層保護。
如果您接手的舊專案滿是 Scriptlet,不必一次重寫,可以先把新功能用 EL 與 JSTL 寫,舊頁面在修改時順手轉換。
七、JSP 與 PHP、ASP.NET 差在哪?
三者都是「伺服器端產生 HTML」的技術,差別在語言、執行環境與生態。只列對決策最有影響的三點,各技術的完整介紹請看各自專文:
- 語言與型別:JSP 背後是 Java,強型別、需要編譯;PHP 是直譯式、弱型別,改完存檔就能看結果;ASP.NET 以 C# 為主,同樣是編譯式強型別。
- 主機門檻:PHP 幾乎所有虛擬主機都內建;JSP 需要 Tomcat 等 Java 容器,記憶體需求較高,多半要租 VPS 或雲端主機;ASP.NET Core 可跑 Linux,但舊版 ASP.NET 綁 Windows。
- 典型應用:JSP 常見於銀行、政府、ERP 等大型 Java 系統;PHP 主宰中小企業官網、WordPress 與電商套件;ASP.NET 多見於微軟生態的企業內部系統。
整體前後端技術怎麼搭、哪種專案該選哪種語言,〈網頁程式設計入門〉有系統性的整理,本文不重複。
八、JSP 在 2026 年的定位:還值得學嗎?
JSP 沒有死,但已經退到「維護既有系統」的位置;新專案很少以 JSP 當畫面層。三個事實可以說明它現在的處境:
- 規格仍在更新:Jakarta Server Pages 隨 Jakarta EE 持續發版,Tomcat 10.1 與 11 都內建支援,所以既有系統升級容器不成問題,只要處理
javax改jakarta的命名空間。 - 主流框架不再優先支援:Spring Boot 官方文件明列 JSP 的限制,例如打包成可執行 jar 時 JSP 無法使用,因此 Spring 生態普遍改用 Thymeleaf 等範本引擎。
- 架構潮流轉向前後端分離:新系統多由 Java 只提供 REST API,畫面交給 React、Vue 等前端框架,伺服器端已經不產生 HTML。
所以答案分兩種人:如果您在台灣的金融、政府、製造業資訊部門工作,或要接手維護既有 Java 系統,JSP 與 JSTL 仍是必備能力,而且這類系統的壽命通常以十年計;如果您是想從零開始學網頁開發的新手,把 Java 學好、再學 Spring Boot 與前端框架,JSP 只需要看得懂即可。
九、網站主的視角:JSP 網站的主機與維護
對非工程背景的網站主來說,JSP 網站最大的差別不在語法,而在主機與人力。我們替企業評估舊網站改版時,遇到 JSP 站點會先看四件事:
- 主機類型:台灣主流虛擬主機以 PHP 與 MySQL 為主,很少提供 Tomcat。JSP 站通常跑在自有伺服器、VPS 或雲端主機上,月費與管理成本都高於共享主機,搬家前要先確認新環境能跑 Java。
- Java 版本:很多舊站停在 Java 8 與 Tomcat 7、8,升級到 Java 17 或 21 時,除了命名空間,還要處理停用的 API 與第三方套件相容性,這是報價落差最大的一項。
- 誰能維護:會 Java 的工程師不少,但願意維護 Scriptlet 滿天飛的舊 JSP 專案的人不多。交接時務必拿到完整原始碼、建置方式與資料庫結構文件。
- SEO 體質:JSP 本身對搜尋引擎沒有壞處,伺服器端輸出的 HTML 反而利於索引;常見問題是網址帶
;jsessionid=參數造成重複內容,以及缺少壓縮與快取設定,這些屬於技術 SEO的範圍,與語言無關。
本站(newscan.com.tw)以 PHP 建置,原因正是第一點:對以官網與詢問單為目標的中小企業,PHP 主機的普及度與成本優勢很明確。但這不代表 JSP 站該改寫,運作正常、能找到人維護的系統,重寫的風險往往高於維持。
十、結論
JSP 是把 Java 嵌進 HTML、由伺服器產生動態網頁的技術,語法核心只有四種標籤,真正的難點在架構:把邏輯留在 Servlet、畫面交給 EL 與 JSTL。它在新專案裡的地位已被前後端分離與其他範本引擎取代,但在企業既有系統中仍會存在很久。
學習順序建議:先把 HTML 與 JavaScript 基礎打穩,再學 Java 與 Servlet,最後才碰 JSP 與 JSTL;順序反過來,會不知道 JSP 到底在替誰省工。
十一、常見問答 FAQ
JSP 是什麼?
JSP 和 Java、Servlet 差在哪?
JSP 現在還有人用嗎?2026 年還值得學嗎?
JSP 和 PHP 哪個好?
.jsp 檔案要怎麼開啟或執行?
參考來源
- Jakarta EE Working Group,〈Jakarta Server Pages〉,Eclipse Foundation 官方規格。
- Apache Software Foundation,〈Jasper 2 JSP Engine How To〉,Apache Tomcat 官方文件。
- Spring,〈Spring Boot Reference:JSP Limitations〉,Spring 官方文件。
- Oracle,〈The Java EE Tutorial:JavaServer Pages Technology〉,Oracle 官方文件。
- OWASP,〈SQL Injection Prevention Cheat Sheet〉,OWASP Cheat Sheet Series。
- 新視野網頁設計,〈網頁程式設計:打造專業網站的必學技術與技巧〉,本站自有內容。
文中 Jakarta EE、Tomcat 與 Spring Boot 的支援狀態依 2026 年 9 月查閱的官方文件整理;第九節為本站承接網站改版評估時的實務檢查項目,不涉及特定客戶資料。