承接上篇資料庫與 POPO 設計,本篇實作留言列表頁面,採用 JSTL (JSP Standard Tag Library) 替代傳統 Scriptlet,實現「視圖與邏輯分離」,代碼更整潔、易維護。
parent_id = 0)Servlet / Controller 將分頁資料放入 request 域:
request.setAttribute("page", pageBean); // 包含 list、totalCount、pageSize、currentPage 等
request.getRequestDispatcher("/WEB-INF/jsp/list_jstl.jsp").forward(request, response);

<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="https://java.sun.com/jsp/jstl/fmt" %>
<html>
<head><title>留言列表 (JSTL)</title></head>
<body>
<h2>留言板 - 主題列表</h2>
<table border="1" cellpadding="5" cellspacing="0" width="100%">
<tr style="background:#f0f0f0">
<th>標題</th><th>作者</th><th>發文時間</th><th>回覆數</th><th>操作</th>
</tr>
<c:forEach var="msg" items="${page.list}">
<tr>
<td><c:out value="${msg.title}" /></td>
<td><c:out value="${msg.user.username}" /></td>
<td><fmt:formatDate value="${msg.postTime}" pattern="yyyy-MM-dd HH:mm" /></td>
<td><c:out value="${msg.replyCount}" /></td>
<td>
<a href="detail?id=${msg.id}">詳情</a> |
<a href="replyForm?parentId=${msg.id}">回覆</a> |
<a href="delete?id=${msg.id}" onclick="return confirm('確定刪除?')">刪除</a>
</td>
</tr>
</c:forEach>
</table>
<!-- 分頁導航 -->
<div style="text-align:center; margin-top:10px">
<c:url value="list" var="baseUrl">
<c:param name="pageNo" value="1" /></c:url>
<a href="${baseUrl}">首頁</a>
<c:if test="${page.currentPage > 1}">
<c:url value="list" var="prevUrl">
<c:param name="pageNo" value="${page.currentPage - 1}" /></c:url>
<a href="${prevUrl}">上一頁</a>
</c:if>
<c:forEach var="i" begin="1" end="${page.totalPage}">
<c:choose>
<c:when test="${i == page.currentPage}">[${i}]</c:when>
<c:otherwise>
<c:url value="list" var="pageUrl">
<c:param name="pageNo" value="${i}" /></c:url>
<a href="${pageUrl}">${i}</a>
</c:otherwise>
</c:choose>
</c:forEach>
<c:if test="${page.currentPage < page.totalPage}">
<c:url value="list" var="nextUrl">
<c:param name="pageNo" value="${page.currentPage + 1}" /></c:url>
<a href="${nextUrl}">下一頁</a>
</c:if>
<c:url value="list" var="lastUrl">
<c:param name="pageNo" value="${page.totalPage}" /></c:url>
<a href="${lastUrl}">尾頁</a>
</div>
</body></html>
| 標簽 | 用途 |
|---|---|
<c:forEach> | 遍歷集合/範圍,替代 for 迴圈 |
<c:out> | 輸出變數,自動 HTML 轉義防 XSS |
<fmt:formatDate> | 日期格式化,替代 SimpleDateFormat |
<c:url> | 自動補全 Context Path,支援參數編碼 |
<c:if>/<c:choose> | 條件判斷,替代 if/else Scriptlet |
<c:out> 預防 XSS 攻擊。下一篇將展示傳統 JSP Scriptlet 寫法對比,幫助理解為何推薦 JSTL。