在基於 HTTP 協議的 JSP/Servlet 應用中,請求參數預設以 ISO-8859-1 (Latin-1) 傳輸,導致中文參數直接取得時變成亂碼。本文提供三大核心場景的標準轉換方案,徹底解決中文編碼難題。
當瀏覽器以 UTF-8 編碼送出表單 ( `
String utf8Value = request.getParameter("name"); // 取得錯誤解碼的字串 byte[] bytes = utf8Value.getBytes("ISO-8859-1"); // 還原原始位元組 String gb2312Value = new String(bytes, "GB2312"); // 正確解碼為中文
原理: Servlet 容器預設用 ISO-8859-1 解碼 URL/表單參數,將 UTF-8 的多位元組序列誤解為單字元。透過 getBytes("ISO-8859-1") 可無損取回原始位元組陣列,再以正確字集重建字串。
getBytes("ISO-8859-1")
網路資料流可能分多次到達,不可假設一次 read() 即讀完。正確迴圈讀取模式:
read()
ServletInputStream in = request.getInputStream(); int total = request.getContentLength(); // 已知長度 byte[] buffer = new byte[4096]; // 緩衝區 byte[] result = new byte[total]; // 最終結果 int readTotal = 0; while (readTotal < total) { int n = in.read(buffer); // 實際讀取位元組數 if (n == -1) break; // 流提前結束 System.arraycopy(buffer, 0, result, readTotal, n); readTotal += n; } // result 現在包含完整請求主體
關鍵點:使用 System.arraycopy 高效複製,避免手工迴圈效能損耗。
System.arraycopy
當 Content-Length 不存在 (如 Chunked Transfer Encoding),利用 ByteArrayOutputStream 自動擴容:
Content-Length
ByteArrayOutputStream
ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[4096]; int n; while ((n = in.read(buffer)) != -1) { baos.write(buffer, 0, n); } byte[] result = baos.toByteArray(); // 自動產生適當大小陣列
優勢:無需預知長度,記憶體管理自動化,程式碼最簡潔。
與其到處手動轉碼,不如在源頭統一:
掌握編碼轉換本質,配合全站統一 UTF-8 策略,中文亂碼將成為歷史。
痛點背景 從 Visual Studio 轉戰 MyEcli
簡介 Thumbnailator 是一個流暢式 API 的
前言 Java 反射允許運行時動態獲取類信息並調用方法,打破
Java Number 類與包裝類完全指南:自動裝箱拆箱、常