下拉列表(<select>)動態綁定是 JSP 最常見場景。標準做法:Controller 查詢數據 → 放入 Request 屬性 → JSP 用 JSTL <c:forEach> 遍歷渲染 <option>。本文給出最小完整示例與進階技巧。
public class Student {
private Integer id;
private String name;
// getter/setter/toString
// 建議實現 equals/hashCode 基於 id,便於 selected 判斷
}
@WebServlet("/student/list")
public class StudentListServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
List<Student> students = studentService.findAll(); // 模擬數據
req.setAttribute("students", students); // 關鍵:放入 Request 域
req.getRequestDispatcher("/WEB-INF/views/student-form.jsp").forward(req, resp);
}
}
<%@ page contentType="text/html;charset=UTF-8" %>
<%@ taglib prefix="c" uri="https://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head><title>學生選擇</title></head>
<body>
<form action="/submit" method="post">
<label>學生:
<select name="studentId">
<option value="">-- 請選擇 --</option>
<c:forEach items="${students}" var="stu">
<option value="${stu.id}" ${stu.id == param.studentId ? 'selected' : ''}>${stu.name}</option>
</c:forEach>
</select>
</label>
<button type="submit">提交</button>
</form>
</body>
</html>
| 技術點 | 說明 |
|---|---|
${students} | EL 表達式自動查找 pageScope → requestScope → sessionScope → applicationScope,匹配 req.setAttribute("students", ...) |
var="stu" | 循環變量名,作用域僅在 <c:forEach> 體內 |
${stu.id} / ${stu.name} | 調用 POJO 的 getId() getName(),**必須有標準 getter** |
${stu.id == param.studentId ? 'selected' : ''} | 回顯已選值:param 為請求參數 Map,編輯/錯誤回顯時自動選中 |
value="" 佔位選項 | 引導用戶主動選擇,防止默認提交第一項 |
<optgroup><c:forEach items="${departments}" var="dept">
<optgroup label="${dept.name}">
<c:forEach items="${dept.students}" var="stu">
<option value="${stu.id}">${stu.name}</option>
</c:forEach>
</optgroup>
</c:forEach>
multiple + 數組綁定<select name="studentIds" multiple>
<c:forEach items="${students}" var="stu">
<option value="${stu.id}" ${fn:contains(paramValues.studentIds, stu.id) ? 'selected' : ''}>${stu.name}</option>
</c:forEach>
</select>
<%@ taglib prefix="fn" uri="https://java.sun.com/jsp/jstl/functions" %>
Controller 接收:String[] studentIds = req.getParameterValues("studentIds");
/api/provinces 返回 JSON 列表,JS 渲染省份 <select>。/api/cities?provinceId=xxx。<c:forEach items="${null}"> 不報錯但不輸出,建議 Controller 保證 new ArrayList<>() 而非 null。${stu.name} 會拋 PropertyNotFoundException,必須生成 getName()。pageEncoding=UTF-8、Servlet req.setCharacterEncoding("UTF-8")、Tomcat URIEncoding=UTF-8 三位一體。JSTL <c:forEach> + EL 表達式是 JSP 綁定集合數據的標準模式,代碼簡潔、零 Java 腳本、天然支持回顯與分組,掌握此模式即可覆蓋 90% 下拉列表場景。