在 Java Web 開發中,HttpServletRequest 的 getParameter() 與 getAttribute() 是最常用也最易混淆的兩個方法。本文從數據來源、生命週期、類型、典型場景四個維度徹底釐清二者區別。
| 維度 | getParameter() | getAttribute() |
|---|---|---|
| 數據來源 | HTTP 請求參數(URL 查詢字符串、POST 表單體、multipart 文件上傳) | 服務器內部設置(Servlet/JSP/Filter 通過 setAttribute 存入) |
| 生命週期 | 隨請求創建,請求結束銷毀 | 隨請求創建,請求結束銷毀(但可跨 forward 傳遞) |
| 數據類型 | 永遠是 String(或 String[]) | 任意 Object |
| 可讀/可寫 | 只讀(無 setParameter) | 可讀可寫(setAttribute/getAttribute) |
| 典型場景 | 接收前端提交的表單數據、查詢參數 | 請求轉發(forward)時在組件間共享數據、Filter 預處理結果傳遞 |
| 作用域 | 整個 Web 應用可見(客戶端可構造) | 僅在服務端請求處理鏈中可見 |
?username=zhangsan&age=20 → request.getParameter("username") 返回 "zhangsan"Content-Type: application/x-www-form-urlencoded,Body 同 GET 格式@MultipartConfig 或 Commons FileUpload 解析
// JSP 表單提交
<form method="post" action="process.jsp">
用戶名:<input name="username">
<input type="submit">
</form>
// process.jsp 接收
String username = request.getParameter("username"); // 返回 String
String[] hobbies = request.getParameterValues("hobby"); // 多值字段(如 checkbox)
RequestDispatcher.forward() 跨組件傳遞對象
// A.jsp / Servlet A:設置屬性並轉發
request.setAttribute("user", userObject); // 存入任意對象
request.getRequestDispatcher("/B.jsp").forward(request, response);
// B.jsp / Servlet B:獲取屬性
User user = (User) request.getAttribute("user"); // 需強制轉型
關鍵點:forward 時 同一個 Request 對象 傳遞給目標資源,屬性得以保留。而 redirect (sendRedirect) 會發起新請求,屬性丟失(需用 Session)。
setAttribute,完全可控,可存放 JavaBean、List、Map、Connection 等任意對象。| 場景 | 方案 A:參數傳遞 | 方案 B:屬性傳遞 |
|---|---|---|
| JSP → Servlet | <a href="servlet?uid=1001"> → getParameter("uid") | 不可直接用(需前端構造 URL) |
| Servlet → JSP (forward) | 不可用(參數不隨 forward 傳遞) | setAttribute("user", u) → getAttribute("user") ✓ |
| Filter → Servlet | 不可用 | setAttribute("cleanParam", val) → getAttribute("cleanParam") ✓ |
| 攜帶複雜對象 | 需序列化為 JSON/字符串,繁瑣且易出錯 | 直接存放對象引用,類型安全、性能高 ✓ |
ParameterMap(通常是 HashMap<String, String[]>) → 只讀暴露。AttributeMap(HashMap<String, Object>) → 開發者隨意增刪改查。誤區:嘗試在 JSP 中直接讀取 JavaScript 變量,或在 JS 中直接讀取 JSP 變量。
真相:JS 運行在瀏覽器(客戶端),JSP 運行在服務器,兩者不同運行時,無法直接訪問彼此變量。
正確橋接:
<script> var uid = '<%= userId %>'; </script>(模板渲染時內嵌)<input type="hidden" name="uid" id="uid"> + JS 賦值 document.getElementById('uid').value = xxx → 提交表單 → getParameter("uid")forward 傳遞Java 對象 → setAttribute()/getAttribute()HttpSession 或 數據庫/Redis。