首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java Web 使用 POST 方法提交數據到 Tomcat 完整實戰:從表單到 Servlet 的編碼處理

     編輯:Java 相關知識

GET vs POST 核心差異

維度GETPOST
參數位置URL 查詢字符串HTTP 請求體
長度限制瀏覽器/服務器限制 (~2KB)理論無限(受 postMaxSize 限制)
可見性地址欄可見、歷史記錄、日誌不可見(需開發者工具查看)
編碼處理Tomcat URIEncoding 解碼 URLreq.setCharacterEncoding() 解碼 Body
冪等性是(查詢)否(修改狀態)
緩存/書籤可緩存、可收藏不可緩存、不可收藏

完整實戰流程

1. 前端表單 (index.jsp)


<%@ page pageEncoding="UTF-8" %>



    
    登入頁面


    
用戶名:
密碼:

關鍵點:

  • method="post" 指定 POST 提交
  • pageEncoding="UTF-8" + <meta charset="UTF-8"> 確保頁面編碼
  • 使用 EL 表達式 ${pageContext.request.contextPath} 動態生成路徑

2. 登入 Servlet 處理 POST 請求


@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"); } }

3. 受保護頁面


<%@ 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 請求體解碼流程

瀏覽器發送 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"})

進階:Multipart 文件上傳 (POST)


文件:
// 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); } }

安全最佳實踐

  • CSRF 防護:表單隱藏 <input type="hidden" name="csrfToken" value="${sessionScope.csrfToken}">,Servlet 驗證
  • 密碼傳輸:生產環境必須 HTTPS,防止明文密碼被竊聽
  • 輸入驗證:長度、格式、特殊字符過濾,防 XSS/SQL 注入
  • 錯誤信息:不提示「用戶不存在」vs「密碼錯誤」,統一「用戶名或密碼錯誤」防用戶枚舉
  • 限流:登入失敗計數 + 驗證碼 + IP 限流

總結

POST 提交核心在於:form method="post"、req.setCharacterEncoding("UTF-8") 必須在 getParameter 前調用、Tomcat URIEncoding=UTF-8 兜底、響應雙重設置編碼。掌握這幾點,配合 HTTPS、CSRF Token、輸入驗證,即可構建安全可靠的表單提交處理流程。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved