JSP 指令元素完整指南
JSP 指令 (<%@ directive %>) 在 編譯階段 (翻譯成 Servlet) 生效,指示容器如何處理頁面。三種指令:page、include、taglib。
1. page 指令 — 頁面屬性設定
<%@ page
language="java"
contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
session="true"
buffer="8kb"
autoFlush="true"
errorPage="/error/500.jsp"
isErrorPage="false"
import="java.util.*, java.sql.*"
extends="com.example.BaseServlet"
info="會員管理頁面"
isThreadSafe="true"
isELIgnored="false"
isScriptingEnabled="true"
%>
屬性完整對照表
| 屬性 | 預設值 | 說明 |
language | java | 腳本語言 (目前僅支援 java) |
contentType | text/html;charset=ISO-8859-1 | 回應 MIME 型別與字元集 必須設定 UTF-8 |
pageEncoding | ISO-8859-1 | JSP 檔案本身編碼 必須設定 UTF-8 |
session | true | 是否自動建立/使用 HttpSession |
buffer | 8kb | out 緩衝區大小,none 關閉緩衝 |
autoFlush | true | 緩衝區滿時自動 flush,false 則拋出例外 |
errorPage | 無 | 發生未捕獲例外時轉發的錯誤頁面路徑 |
isErrorPage | false | 是否為錯誤頁面 (可使用 exception 隱含物件) |
import | 無 | 匯入 Java 套件/類別,多值用逗號分隔 |
extends | 容器預設 | 生成 Servlet 繼承的父類別 (罕用) |
info | 無 | 頁面描述,可透過 Servlet.getServletInfo() 取得 |
isThreadSafe | true | 是否支援多執行緒並發 (false 會同步 service 方法) |
isELIgnored | false (2.5+) | true 則忽略 EL 運算式視為純文字 |
isScriptingEnabled | true | false 則禁止 Scriptlet/Declaration/Expression |
XML 等價語法
<jsp:directive.page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" />
2. include 指令 — 靜態包含
<%@ include file="relative/path/header.jsp" %>
- 編譯期合併:被包含檔案內容直接插入當前 JSP,重新編譯成單一 Servlet
- 被包含檔案可包含 JSP 程式碼、指令、動作元素
- 變數名稱衝突風險 (同一 Servlet 內)
- 檔案變更需重新編譯主頁面才生效
- 適用於靜態片段:頁首、頁尾、導航欄、共用變數宣告
XML 等價語法
<jsp:directive.include file="header.jsp" />
3. taglib 指令 — 引入標籤庫
<%@ taglib uri="https://java.sun.com/jsp/jstl/core" prefix="c" %>
uri:標籤庫唯一識別 URI (對應 TLD 檔案 <uri> 或 web.xml 映射)
prefix:標籤前綴,頁面中使用 <c:forEach>
- 常用標籤庫 URI:
- JSTL Core:
https://java.sun.com/jsp/jstl/core
- JSTL Format:
https://java.sun.com/jsp/jstl/fmt
- JSTL Functions:
https://java.sun.com/jsp/jstl/functions
- JSTL SQL:
https://java.sun.com/jsp/jstl/sql
- JSTL XML:
https://java.sun.com/jsp/jstl/xml
XML 等價語法
<jsp:directive.taglib uri="https://java.sun.com/jsp/jstl/core" prefix="c" />
指令 vs 動作元素 vs Scriptlet 執行時機比較
| 類別 | 語法範例 | 階段 | 可動態變化 | 典型用途 |
| page 指令 | <%@ page ... %> | 編譯期 | 否 | 編碼、緩衝區、錯誤頁、匯入 |
| include 指令 | <%@ include file="..." %> | 編譯期 | 否 | 靜態片段合併 |
| taglib 指令 | <%@ taglib ... %> | 編譯期 | 否 | 標籤庫宣告 |
| jsp:include | <jsp:include page="..." /> | 請求期 | 是 | 動態包含、傳參數 |
| jsp:forward | <jsp:forward page="..." /> | 請求期 | 是 | 請求轉發 |
| Scriptlet | <% java code %> | 請求期 | 是 | 任意邏輯 (建議最小化) |
常見組合最佳實踐
標準頁面模板 (建議每頁開頭)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"
isELIgnored="false" isScriptingEnabled="true"
errorPage="/error/500.jsp" %>
<%@ taglib uri="https://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="https://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="https://java.sun.com/jsp/jstl/functions" prefix="fn" %>
錯誤頁面模板
<%@ page isErrorPage="true" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title>系統錯誤</title></head>
<body>
<h1>發生錯誤</h1>
<p><c:out value="${exception.message}" /></p>
<% if (exception != null) { %>
<pre><%= exception.getClass().getName() %>
<% for (StackTraceElement e : exception.getStackTrace()) out.println("\tat " + e); %>
</pre>
<% } %>
</body></html>
共用片段 (include 指令)
<%-- _header.jsp --%>
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<header><nav>...</nav></header>
<%-- main.jsp --%>
<%@ include file="_header.jsp" %>
<main>...</main>
<%@ include file="_footer.jsp" %>
注意事項
- 編碼雙重設定:
contentType 設定回應標頭 charset,pageEncoding 設定檔案讀取編碼,兩者必須一致 (UTF-8)。
include 指令包含檔案不需完整 HTML 結構,僅片段內容。
taglib 的 uri 必須與 TLD 定義一致,容器自動從 WEB-INF/lib/*.jar/META-INF/*.tld 掃描。
isScriptingEnabled="false" 可強制團隊避免 Scriptlet,配合 Code Review 執行。
- 錯誤頁面
errorPage 路徑以 / 開頭表示相對 Context Root。