JSP 內置對象是 Web 容器 (Tomcat) 自動創建、無需 new 即可直接在 JSP 頁面使用的 9 個核心對象。本文系統介紹各對象職責、作用域、核心方法,並通過完整代碼示例演示 request 參數獲取、中文亂碼解決、request 轉發與 response 重定向的差異、session/application 數據共享。
| 對象 | 類型 | 作用域 | 核心用途 |
|---|---|---|---|
| out | JspWriter | 頁面 | 輸出響應內容,管理緩衝區 |
| request | HttpServletRequest | 請求 | 獲取請求參數、頭信息、屬性 |
| response | HttpServletResponse | 頁面 | 設置響應頭、狀態碼、重定向 |
| session | HttpSession | 會話 | 用戶狀態保持、跨請求數據共享 |
| application | ServletContext | 應用 | 全局配置、緩存、監聽器上下文 |
| pageContext | PageContext | 頁面 | 訪問其他 8 大對象、屬性管理 |
| config | ServletConfig | 應用 | 獲取 Servlet 初始化參數 |
| page | Object (this) | 頁面 | 當前 JSP 實例引用 |
| exception | Throwable | 頁面 | 錯誤頁面 (isErrorPage=true) 異常處理 |
<%@ page pageEncoding="UTF-8"%>
<form action="index.jsp" method="post">
用戶名: <input name="txtName"/><br/>
密碼: <input type="password" name="txtPwd"/><br/>
<input type="submit" value="登錄"/>
</form>
<%@ page pageEncoding="UTF-8"%>
<%
// 核心:必須在獲取參數前設置編碼,僅對 POST 有效
request.setCharacterEncoding("UTF-8");
%>
<%
String name = request.getParameter("txtName");
String pwd = request.getParameter("txtPwd");
%>
用戶名: <%=name %><br/>
密碼: <%=pwd %>
原理:Tomcat 默認用 ISO-8859-1 解碼 POST 體,設置 UTF-8 後重新解碼。GET 請求參數在 URL 中,需在 server.xml <Connector URIEncoding="UTF-8"/> 解決。
<%-- 2.jsp --%>
<% if ("123".equals(request.getParameter("txtName"))) {
String str = request.getParameter("txtName");
request.setAttribute("name", str); // request 域攜帶數據
request.getRequestDispatcher("index.jsp").forward(request, response);
} %>
現象:瀏覽器地址欄仍顯示 2.jsp,但頁面內容為 index.jsp 渲染結果。request 域數據保留。
<% if ("123".equals(request.getParameter("txtName"))) {
String str = request.getParameter("txtName");
request.setAttribute("name", str); // 注意:重定向後 request 域失效!
response.sendRedirect("index.jsp"); // 瀏覽器發起新請求
} %>
現象:瀏覽器地址欄變為 index.jsp。request 域數據丟失,需用 session 或 URL 參數傳遞。
| 特性 | forward (轉發) | sendRedirect (重定向) |
|---|---|---|
| 請求次數 | 1 次 | 2 次 (302 + 新請求) |
| 地址欄 | 不變 | 改為目標 URL |
| request 域 | 共享 | 不共享 (新 request) |
| 訪問範圍 | 同一 Web 應用 | 任意 URL (含外部站點) |
| 性能 | 略高 | 略低 |
| 適用場景 | 業務流程內部跳轉、需共享請求數據 | 表單提交後 (PRG 模式)、跨應用/外部跳轉 |
<!-- 頁面 A 存入 --%>
<% session.setAttribute("username", username); %>
<!-- 頁面 B 取出 --%>
<% String username = (String) session.getAttribute("username"); %>
默認 30 分鐘無操作失效,可在 web.xml 配置 <session-config><session-timeout>60</session-timeout></session-config>。
application (全局應用級)
<% application.setAttribute("globalConfig", configObj); %>
<% Object cfg = application.getAttribute("globalConfig"); %>
生命週期 = 容器啟動到關閉。配合 ServletContextListener 監聽屬性變更/容器啟動銷毀。
五、out 對象輸出示例
<% out.print("我是 out 內置對象輸出的內容"); %>
六、總結
掌握九大內置對象的作用域邊界與核心 API,是 JSP/Servlet 開發的基石。重點記住:request 僅一次請求、session 跨請求同用戶、application 全局共享;轉發共享 request、重定向不共享;POST 亂碼必須 request.setCharacterEncoding。現代開發多用 SpringMVC 替代原始 JSP/Servlet,但原理不變,理解透徹受益終身。