Servlet 請求參數可能來自查詢字符串 (GET)、表單體 (POST)、multipart 文件上傳。本文提供遍歷所有參數的標準代碼,並補充多值參數處理、編碼設置、文件上傳參數區別與 Spring MVC 綁定對比。
標準遍歷代碼
public static Map getAllParams(HttpServletRequest request) {
Map params = new LinkedHashMap<>(); // 保留順序
Enumeration names = request.getParameterNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
// getParameter 返回首個值 (多值取第一個)
String value = request.getParameter(name);
params.put(name, value);
}
return params;
}
// 獲取所有值 (多值參數如 checkbox、多文件)
public static Map> getAllParamsMulti(HttpServletRequest request) {
Map> params = new LinkedHashMap<>();
Enumeration names = request.getParameterNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
String[] values = request.getParameterValues(name);
params.put(name, Arrays.asList(values));
}
return params;
}
JSP 中直接輸出 (調試用)
<%@ page import="java.util.*" %>
<%
Enumeration names = request.getParameterNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
String value = request.getParameter(name);
out.println(name + " = " + value + "
");
}
%>
關鍵 API 對比
| 方法 | 返回 | 用途 |
| getParameter(name) | String | 單值 (首個) |
| getParameterValues(name) | String[] | 所有值 |
| getParameterNames() | Enumeration | 所有參數名 |
| getParameterMap() | Map | 完整參數映射 (Spring 內部使用) |
編碼問題與解決
| 場景 | 問題 | 解決 |
| GET 請求中文亂碼 | Tomcat 8+ 默認 UTF-8,舊版本 ISO-8859-1 | server.xml `` 或 Filter 設置 |
| POST 表單亂碼 | 請求體編碼未設置 | Filter 首行 `request.setCharacterEncoding("UTF-8")` |
| multipart 文件上傳 | 參數非 getParameter 可獲取 | 用 Commons FileUpload / Servlet 3.0 `request.getPart()` |
Filter 統一設置編碼 (生產必備)
@WebFilter("/*")
public class EncodingFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
chain.doFilter(request, response);
}
}
Spring MVC 參數綁定 (推薦替代手動遍歷)
| 場景 | 註解 | 示例 |
| 單個參數 | @RequestParam | @RequestParam("name") String name |
| 可選參數 | @RequestParam(required=false) | @RequestParam(value="age", required=false) Integer age |
| 默認值 | @RequestParam(defaultValue="10") | @RequestParam(defaultValue="10") int size |
| 所有參數綁定 Map | @RequestParam Map | @RequestParam Map params |
| 對象綁定 (表單/JSON) | @ModelAttribute / @RequestBody | @ModelAttribute UserForm form |
| 多值參數 | @RequestParam List | @RequestParam List ids |
文件上傳參數特殊處理
// Servlet 3.0+ 標準 API
@MultipartConfig
@WebServlet("/upload")
public class UploadServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 普通表單字段
String username = req.getParameter("username");
// 文件部分
Part filePart = req.getPart("file");
String fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString();
try (InputStream is = filePart.getInputStream()) {
Files.copy(is, Paths.get("/uploads", fileName));
}
}
}
常見坑點
- ❌ `getParameter` 在調用過 `getReader()`/`getInputStream()` 後返回 null (流已消費)。
- ❌ GET 請求參數在 URL 中,POST 在 Body,但 API 統一用 `getParameter`。
- ❌ 多值參數 (如 `
- ❌ 文件上傳 `enctype="multipart/form-data"` 時,普通參數也能用 `getParameter` 獲取 (Servlet 3.0+),但文件需用 `getPart`。
總結
- 手動遍歷用 `getParameterNames()` + `getParameter()`/`getParameterValues()`。
- 編碼統一 UTF-8:Tomcat 配置 + Filter `setCharacterEncoding`。
- Spring MVC 專案**優先用註解綁定**,避免手動遍歷、類型轉換、校驗分散。
- 文件上傳用 Servlet 3.0 `Part` API 或 Spring `MultipartFile`。
- 調試頁面可直接在 JSP 中遍歷輸出,生產環境移除。