對比上篇 JSTL 版,本篇用Scriptlet實現相同的發文頁面,直觀展示驗證邏輯分散、CSRF 處理繁瑣、HTML5 屬性與 Java 代碼混雜等痛點。

<%@ page contentType="text/html;charset=UTF-8" import="java.util.*" %>
<html><head><title>發布主題</title>
<style>.error{color:red} textarea{width:100%;height:150px}</style></head><body>
<h2>發布新主題</h2>
<%
Map<String,String> errors = (Map<String,String>) request.getAttribute("errors");
User loginUser = (User) session.getAttribute("loginUser");
String csrfToken = (String) session.getAttribute("csrfToken");
%>
<form action="postSubmit" method="post">
<input type="hidden" name="csrfToken" value="<%= csrfToken %>" />
<input type="hidden" name="userId" value="<%= loginUser.getId() %>" />
<div>
<label>標題(必填):</label>
<input type="text" name="title" size="80" maxlength="200" required
value="<%= request.getParameter("title") != null ? request.getParameter("title") : "" %>" />
<% if (errors != null && errors.get("title") != null) { %>
<span class="error"><%= errors.get("title") %></span>
<% } %>
</div>
<div>
<label>內容(必填):</label><br/>
<textarea name="content" required><%= request.getParameter("content") != null ? request.getParameter("content") : "" %></textarea>
<% if (errors != null && errors.get("content") != null) { %>
<span class="error"><%= errors.get("content") %></span>
<% } %>
</div>
<div>
<input type="submit" value="發布" />
<input type="button" value="取消" onclick="history.back()" />
</div>
</form>
</body></html>
value 都要寫 request.getParameter("x") != null ? ... : "",JSTL 一個 ${param.x} 搞定。errors != null && errors.get("x") != null 重複寫;JSTL ${errors.x} 自動安全導航。<%= csrfToken %> 直接輸出,若 Token 含特殊字元需手動轉義;JSTL <c:out> 自動處理。<%= ... %> 直接輸出,極易造成 XSS。jsp:include 抽取通用片段(表頭、表尾、錯誤顯示片段),減少重複 Scriptlet。系列最後一篇將介紹 Hibernate 整合,展示 ORM 如何簡化 DAO/Service 代碼。