| 維度 | GET | POST |
|---|---|---|
| 參數位置 | URL 查詢字符串 | HTTP 請求體 |
| 長度限制 | 瀏覽器/服務器限制 (~2KB) | 理論無限(受 postMaxSize 限制) |
| 可見性 | 地址欄可見、歷史記錄、日誌 | 不可見(需開發者工具查看) |
| 編碼處理 | Tomcat URIEncoding 解碼 URL | req.setCharacterEncoding() 解碼 Body |
| 冪等性 | 是(查詢) | 否(修改狀態) |
| 緩存/書籤 | 可緩存、可收藏 | 不可緩存、不可收藏 |
<%@ page pageEncoding="UTF-8" %>
登入頁面
關鍵點:
method="post" 指定 POST 提交pageEncoding="UTF-8" + <meta charset="UTF-8"> 確保頁面編碼${pageContext.request.contextPath} 動態生成路徑
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// 1. 設置請求體編碼(必須在 getParameter 之前!)
req.setCharacterEncoding("UTF-8");
// 2. 設置響應編碼
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
// 3. 獲取參數
String username = req.getParameter("username");
String password = req.getParameter("password");
// 4. 業務邏輯(示例:硬編碼驗證)
PrintWriter out = resp.getWriter();
if ("admin".equals(username) && "123456".equals(password)) {
// 登入成功:建立 Session
HttpSession session = req.getSession(true);
session.setAttribute("loginUser", username);
session.setMaxInactiveInterval(30 * 60);
out.println("登入成功,歡迎 " + username + "
");
out.println("進入主頁");
} else {
out.println("用戶名或密碼錯誤
");
out.println("返回重試");
}
}
// GET 請求直接轉發到登入頁或拒絕
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.sendRedirect(req.getContextPath() + "/index.jsp");
}
}
<%@ page pageEncoding="UTF-8" %>
<%
HttpSession session = request.getSession(false);
if (session == null || session.getAttribute("loginUser") == null) {
response.sendRedirect(request.getContextPath() + "/index.jsp");
return;
}
%>
歡迎頁
歡迎, ${sessionScope.loginUser}!
登出
瀏覽器發送 POST: Content-Type: application/x-www-form-urlencoded; charset=UTF-8 Body: username=%E5%BC%A0%E4%B8%89&password=123456 (URL 編碼後的 bytes) Tomcat 接收: 1. 讀取 Content-Type charset → UTF-8 2. 若無 charset,使用 req.setCharacterEncoding() 設置的編碼 3. 若都無,默認 ISO-8859-1 解碼 bytes → 字符串 4. getParameter() 返回解碼後的字符串
| 錯誤現象 | 原因 | 修正 |
|---|---|---|
| 中文參數變 ??? 或亂碼 | 未調用 req.setCharacterEncoding("UTF-8") 或調用太晚 | 在第一行調用,getParameter 前 |
| Tomcat 8/9 默認 ISO-8859-1 | 未配置 URIEncoding、Filter 強制編碼 | server.xml Connector URIEncoding="UTF-8" + EncodingFilter |
| 響應頁面亂碼 | 未設置 resp.setCharacterEncoding + Content-Type charset | 雙重設置,或 JSP pageEncoding |
| AJAX POST 亂碼 | 前端 contentType 未指定 charset | $.ajax({contentType: "application/x-www-form-urlencoded;charset=UTF-8"}) |
// Servlet 3.0+ 原生支援
@WebServlet("/upload")
@MultipartConfig(maxFileSize = 10*1024*1024, maxRequestSize = 50*1024*1024)
public class UploadServlet extends HttpServlet {
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
req.setCharacterEncoding("UTF-8"); // 仍需設置,處理非文件字段
Part filePart = req.getPart("file");
String fileName = Paths.get(filePart.getSubmittedFileName()).getFileName().toString();
filePart.write("/upload/path/" + fileName);
resp.getWriter().println("上傳成功:" + fileName);
}
}
<input type="hidden" name="csrfToken" value="${sessionScope.csrfToken}">,Servlet 驗證POST 提交核心在於:form method="post"、req.setCharacterEncoding("UTF-8") 必須在 getParameter 前調用、Tomcat URIEncoding=UTF-8 兜底、響應雙重設置編碼。掌握這幾點,配合 HTTPS、CSRF Token、輸入驗證,即可構建安全可靠的表單提交處理流程。