首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

HTTP POST 請求伺服器端接收到 null 完整排查指南

     編輯:程式設計綜合問答

現象描述

客戶端發送 HTTP POST 請求,伺服器端 (Servlet/Controller) 通過 `request.getParameter()` 或 `@RequestParam` 獲取參數時均為 `null`,但請求本身已到達伺服器。

核心排查清單 (按可能性排序)

1. Content-Type 標頭缺失或錯誤 ⭐ 最常見

**表單提交**必須設定:`Content-Type: application/x-www-form-urlencoded` (預設) 或 `multipart/form-data` (含檔案)。
**AJAX/JSON 提交**必須設定:`Content-Type: application/json;charset=UTF-8`。
檢查方式:瀏覽器 DevTools → Network → Request Headers 確認。

2. 請求體格式與 Content-Type 不匹配

  • `application/x-www-form-urlencoded` → 體格式 `key1=val1&key2=val2` (URL 編碼)
  • `multipart/form-data` → 體為邊界分隔的多部分內容 (瀏覽器自動構建,JS 需用 `FormData`)
  • `application/json` → 體為 JSON 字串 `{"key":"val"}`

**常見錯誤**:設定 `application/json` 卻發送表單字串,或反之。

3. GET 請求誤用 POST 體 / URL 參數混淆

若程式碼中將參數拼接在 URL (`/api?key=val`) 但方法標註 `@PostMapping`,Spring MVC 預設不解析 URL 參數到 `@RequestParam` (需配置)。
**解決**:參數放請求體,或在方法參數加 `@RequestParam` 並確保 `HttpServletRequest` 可獲取查詢字串。

4. 請求體被過濾器/攔截器預讀取導致流關閉

若自定義 `Filter` 或 `HandlerInterceptor` 中調用了 `request.getInputStream()` 或 `request.getReader()`,**流只能讀取一次**,後續 Controller 無法再讀取。
**解決**:使用 `ContentCachingRequestWrapper` 包裝請求,或避免在過濾器中讀取請求體。

5. 伺服器端參數名稱大小寫/拼寫不匹配

Java 區分大小寫。前端發送 `userName`,後端接收 `username` → `null`。
**解決**:統一命名規範 (camelCase),或使用 `@RequestParam("userName")` 顯式映射。

6. 編碼問題導致解析失敗

請求體含中文但未指定 `charset=UTF-8`,伺服器按 ISO-8859-1 解析導致亂碼或解析異常。
**解決**:全鏈路強制 UTF-8:`encodingFilter...` (Spring `CharacterEncodingFilter`)。

快速定位技巧

  1. **抓包工具**:Wireshark / Fiddler / Charles 捕獲原始 TCP 包,確認請求體確實發送。
  2. **伺服器日誌**:開啟 Tomcat `AccessLogValve` 或 Spring `Debug` 級別日誌,查看解析後的參數 Map。
  3. **測試端點**:暫時建立一個 `@PostMapping("/echo") public String echo(@RequestBody String body) { return body; }` 直接回顯原始請求體,驗證傳輸層無誤。

總結

POST 參數為 null 90% 是 **Content-Type 與請求體格式不匹配** 或 **請求體被提前讀取**。按上述清單逐項排查,通常 5 分鐘內定位問題。

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