前言
JSP 頁面本質是 **Servlet 的模板化表示**。掌握 5 種核心語法元素,能讀懂、寫出、重構任何 JSP 頁面。JSP 1.1+ 已全面支援 XML 兼容語法,建議新項目優先使用。
五大核心語法元素對照表
| 類型 | 傳統語法 | XML 兼容語法 (JSPX) | 用途 | 編譯後 Servlet 位置 |
| 指令 | <%@ page ... %> | <jsp:directive.page ... /> | 頁面屬性:語言、編碼、導入、Session、緩衝、錯誤頁、EL 忽略等 | 類級別 (屬性/導入) |
| 聲明 | <%! 代碼 %> | <jsp:declaration>代碼</jsp:declaration> | 類成員:字段、方法、內部類 (不推薦濫用) | 類體 (成員變量/方法) |
| 腳本片段 | <% 代碼 %> | <jsp:scriptlet>代碼</jsp:scriptlet> | 任意 Java 語句塊:流程控制、變量賦值、邏輯計算 | _jspService() 方法體內 |
| 表達式 | <= 表達式 %> | <jsp:expression>表達式</jsp:expression> | 輸出值到響應流 (自動 toString),**不能以分號結尾** | out.print(表達式) |
| 註釋 | <%-- 註釋 --%> | <!-- jsp:comment -->註釋<!-- /jsp:comment --> | **僅在編譯階段存在**,不輸出到客戶端 (區別 HTML 註釋) | 無 (編譯器忽略) |
完整示例:從傳統到 XML 寫法
傳統 .jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
import="java.util.*,java.text.*"
session="true" buffer="16kb" errorPage="error.jsp" %>
<%@ page isELIgnored="false" %>
<html>
<head><title>JSP 語法演示</title></head>
<body>
<%!
// 聲明:類成員字段/方法
private static final String GREETING = "Hello";
public String formatDate(Date d) {
return new SimpleDateFormat("yyyy-MM-dd HH:mm").format(d);
}
%>
<%
// 腳本片段:請求處理邏輯
String user = request.getParameter("user");
if (user == null || user.trim().isEmpty()) {
user = "Guest";
}
Date now = new Date();
%>
<h1><%= GREETING %>, <%= user %>!</h1>
<p>當前時間: <%= formatDate(now) %></p>
<%--
JSP 註釋:客戶端完全看不見
可包含任意字符,甚至 <% @ %>
--%>
<!-- HTML 註釋:客戶端可見 -->
</body>
</html>
XML 兼容 .jspx (推薦新項目)
<?xml version="1.0" encoding="UTF-8"?>
<jsp:root xmlns:jsp="https://java.sun.com/JSP/Page" version="2.1"
xmlns:c="https://java.sun.com/jsp/jstl/core">
<jsp:directive.page language="java" contentType="text/html; charset=UTF-8"
import="java.util.*,java.text.*" session="true" buffer="16kb"
errorPage="error.jsp" isELIgnored="false"/>
<jsp:declaration>
private static final String GREETING = "Hello";
public String formatDate(Date d) {
return new SimpleDateFormat("yyyy-MM-dd HH:mm").format(d);
}
</jsp:declaration>
<html xmlns="https://www.w3.org/1999/xhtml">
<head><title>JSPX 語法演示</title></head>
<body>
<jsp:scriptlet>
String user = request.getParameter("user");
if (user == null || user.trim().isEmpty()) {
user = "Guest";
}
Date now = new Date();
</jsp:scriptlet>
<h1><jsp:expression>GREETING + ", " + user + "!"</jsp:expression></h1>
<p>當前時間: <jsp:expression>formatDate(now)</jsp:expression></p>
<!-- jsp:comment -->
JSP 註釋:客戶端不可見
<!-- /jsp:comment -->
<!-- HTML 註釋 -->
</body>
</html>
</jsp:root>
隱含對象 (腳本片段/表達式中直接可用)
| 對象 | 類型 | 作用域 | 用途 |
| request | HttpServletRequest | 請求 | 參數、頭部、屬性、轉發 |
| response | HttpServletResponse | 頁面 | 狀態、頭部、Cookie、重定向 |
| out | JspWriter | 頁面 | 輸出響應體 (緩衝) |
| session | HttpSession | 會話 | 用戶狀態、屬性 (需 page 指令 session="true") |
| application | ServletContext | 應用 | 全局配置、資源、屬性 |
| config | ServletConfig | 頁面 | 初始化參數 |
| pageContext | PageContext | 頁面 | 統一作用域訪問、轉發、包含 |
| page | Object (this) | 頁面 | 當前 Servlet 實例引用 |
| exception | Throwable | 錯誤頁 | 異常對象 (需 isErrorPage="true") |
最佳實踐原則 (2024+)
- 零 Scriptlet:業務邏輯移至 Controller/Service/Bean,JSP 僅用 EL/JSTL/標簽庫。
- 零聲明:工具方法放入獨立工具類或 Bean,JSP 不寫
<%! %>。
- 表達式僅輸出簡單值:複雜格式化用 JSTL
<fmt:formatDate> / EL 函數。
- 優先 .jspx:XML 結構利於 IDE 驗證、重構、模板引擎兼容。
- 編碼統一 UTF-8:
pageEncoding="UTF-8" + contentType="text/html; charset=UTF-8"。