對比上篇 JSTL 版,本篇用Scriptlet實現相同的回覆頁面,直觀展示代碼混雜、手動轉義、錯誤處理分散等痛點。

<%@ page contentType="text/html;charset=UTF-8" import="java.util.*,com.example.model.*" %>
<html><head><title>回覆留言</title>
<style>.error{color:red} textarea{width:100%;height:120px}</style></head><body>
<h2>回覆留言</h2>
<%
Message parent = (Message) request.getAttribute("parent");
Map<String,String> errors = (Map<String,String>) request.getAttribute("errors");
User loginUser = (User) session.getAttribute("loginUser");
%>
<fieldset><legend>原貼文</legend>
<strong>標題:</strong><%= parent.getTitle() %><br/>
<strong>作者:</strong><%= parent.getUser().getUsername() %><br/>
<strong>內容:</strong><%= parent.getContent() %>
</fieldset>
<form action="replySubmit" method="post">
<input type="hidden" name="parentId" value="<%= parent.getId() %>" />
<input type="hidden" name="userId" value="<%= loginUser.getId() %>" />
<div>
<label>標題(選填):</label>
<input type="text" name="title" size="60" value="<%= request.getParameter("title") != null ? request.getParameter("title") : "" %>" />
</div>
<div>
<label>內容(必填):</label><br/>
<textarea name="content"><%= 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>
request.getParameter("title") != null ? ... : "" 每個欄位都要寫一次;JSTL 只需 ${param.title}。<%= parent.getTitle() %> 直接輸出,若標題含 <script> 將觸發 XSS;必須手動 StringEscapeUtils.escapeHtml()。get(),JSTL ${errors.content} 自動處理 null。%> 或引號不匹配。"loginUser" 字串分散在多個 JSP,重構時易遺漏。<my:input>、<my:error>)。系列下一篇將進入 Service 層:JDBC 實現留言板核心業務邏輯。