EL (Expression Language) 與 JSTL (JSP Standard Tag Library) 是現代 JSP 開發的**雙子星**:EL 負責**數據輸出與運算**,JSTL 負責**流程控制與結構化邏輯**,徹底替代 JSP 腳本 `<% ... %>`,實現**無腳本 JSP**。本文系統講解 EL 十一大隱含對象、數據訪問規則、運算符、常用函數,以及 JSTL 核心/格式化標簽實戰用法。
${expression}
可嵌套在模板文本中:`你好,${user.name}`。
| 隱含對象 | 類型 | 對應 API | 用途 |
|---|---|---|---|
pageScope | Map | PageContext.getAttribute(name, PAGE_SCOPE) | 頁面域讀取 |
requestScope | Map | request.getAttribute(name) | 請求域讀取 |
sessionScope | Map | session.getAttribute(name) | 會話域讀取 |
applicationScope | Map | application.getAttribute(name) | 應用域讀取 |
param | Map | request.getParameter(name) | 單值請求參數 |
paramValues | Map | request.getParameterValues(name) | 多值請求參數 |
header | Map | request.getHeader(name) | 單值請求頭 |
headerValues | Map | request.getHeaderValues(name) | 多值請求頭 |
cookie | Map | request.getCookies() 轉 Map | Cookie 訪問 |
initParam | Map | application.getInitParameter(name) | 上下文初始化參數 |
pageContext | PageContext | pageContext | 訪問 request/response/session/application 等 |
${username}
== 依次查找:
pageScope["username"] → requestScope["username"] → sessionScope["username"] → applicationScope["username"]
找到即返回,否則返回空字符串 "" (不拋異常)
| 數據結構 | EL 寫法 | 底層調用 | 示例 |
|---|---|---|---|
| JavaBean 屬性 | ${obj.prop} | obj.getProp() | ${user.name} |
| Map 鍵值 | ${map.key} / ${map['key-with-dash']} | map.get("key") | ${userMap['full-name']} |
| List/數組 索引 | ${list[0]} / ${arr[1]} | list.get(0) / arr[1] | ${items[0]} |
| 巢狀訪問 | ${user.address.city} | user.getAddress().getCity() | ${order.buyer.name} |
神奇特性: EL 統一了 `.` 和 `[]` 訪問,**自動處理 null 安全** (鏈路中任一環為 null 整體返回空串而非 NPE)。
<%@ taglib prefix="fn" uri="https://java.sun.com/jsp/jstl/functions" %>
${fn:length(list)} // 集合/數組/字符串長度
${fn:contains(str, substr)} // 包含判斷
${fn:startsWith(str, pre)} // 前綴
${fn:endsWith(str, suf)} // 後綴
${fn:indexOf(str, substr)} // 索引
${fn:substring(str, begin, end)}
${fn:replace(str, before, after)}
${fn:toUpperCase(str)} / ${fn:toLowerCase(str)}
${fn:trim(str)} / ${fn:split(str, delimiter)} / ${fn:join(array, separator)}
<%@ taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core" %>
<c:set var="name" value="張三" scope="request" />
<c:remove var="name" scope="request" />
<c:catch var="exception">${1/0}</c:catch> <!-- 捕獲異常不拋出 -->
<c:if test="${user.role == 'admin'}">
<a href="/admin">管理後台</a>
</c:if>
<c:choose>
<c:when test="${score >= 90}">優秀</c:when>
<c:when test="${score >= 60}">及格</c:when>
<c:otherwise>不及格</c:otherwise>
</c:choose>
<c:forEach var="item" items="${userList}" varStatus="status">
${status.index} : ${item.name} <br/>
</c:forEach>
<c:forEach var="i" begin="1" end="10" step="2">
${i} <br/>
</c:forEach>
<c:url value="/user/detail" var="detailUrl">
<c:param name="id" value="${user.id}"/>
</c:url>
<a href="${detailUrl}">詳情</a>
<!-- 自動補全 contextPath、編碼參數、支援 Session ID 重寫 -->
<c:out value="${user.bio}" escapeXml="true" default="無簡介" />
<!-- 將 < > & " ' 轉為實體字符 -->
<%@ taglib prefix="fmt" uri="https://java.sun.com/jsp/jstl/fmt" %>
<fmt:formatNumber value="${price}" type="currency" currencySymbol="¥" />
<fmt:formatDate value="${order.time}" pattern="yyyy-MM-dd HH:mm" />
<fmt:parseNumber value="1,234.56" type="number" parseLocale="en_US" var="num" />
<fmt:parseDate value="2023-10-01" pattern="yyyy-MM-dd" var="date" />
<fmt:setLocale value="zh_CN" scope="session" />
<fmt:setTimeZone value="GMT+8" />
<fmt:bundle basename="messages">
<fmt:message key="welcome"/>
</fmt:bundle>
EL:簡潔的數據訪問語言,十一隱含對象、空安全鏈式訪問、豐富運算符。
JSTL c: 流程控制 (if/choose/forEach)、變量管理、URL 處理、輸出轉義。
JSTL fmt: 國際化格式化 (數字/日期/消息)。
三者結合 = **專業級無腳本 JSP**,是 Spring MVC/Struts 2 等框架 View 層的標準配置。