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

Java/JSP 中文編碼問題深度解析:從位元組到 Unicode 的完整轉換鏈

     編輯:關於JSP

核心知識:位元組、Char 與 Unicode

  • Java 內核使用 UTF-16 (char),class 檔案常數池採 Modified UTF-8。
  • 外部媒介(檔案、網路、資料庫)多為位元組流,需指定編碼轉換。
  • 關鍵轉換類別:sun.io.ByteToCharConverter、CharToByteConverter(內部實作,建議使用標準 InputStreamReader/OutputStreamWriter)。

編碼轉換實例

以「你」字為例:Big5/GBK = 0xC4E3,Unicode = 0x4F60。

// 位元組 → Char (解碼)
byte[] b = {(byte)0xC4, (byte)0xE3};
String s = new String(b, "GBK");  // 正確得到 "你"
String s2 = new String(b, "8859_1"); // 錯誤得到兩個雜湊字元

// Char → 位元組 (編碼)
char[] c = {'你'};
byte[] b2 = "你".getBytes("GBK");   // {0xC4, 0xE3}
byte[] b3 = "你".getBytes("8859_1"); // {0x3F} ('?') 無法對應

String.length() 回傳 char 數,不同編碼下位元組長度不同,分頁截斷易產生亂碼。

Reader/Writer 與 Stream 的關係

  • InputStreamReader / OutputStreamWriter 是橋樑:建構子必須傳入 encoding,否則用平台預設編碼(中文 Windows = GBK/Big5,Linux/英文 Windows = ISO-8859-1)。
  • 直接使用 FileReader/FileWriter 無法指定編碼,跨平台極不穩定。

Javac 編譯期編碼

javac -encoding GBK MyJsp.java
  • 編譯器依指定編碼讀取 .java,將字面字串編譯為 Modified UTF-8 存入 .class。
  • 若未指定 -encoding,依平台預設編碼讀取 → 跨平台編譯會產生不同 bytecode。
  • 範例:String str = "你"; 在中文平台編譯 → runtime char[] = 0x4F60;英文平台編譯 → runtime char[] = 0x00C4, 0x00E3(誤將位元組當 Unicode)。

JSP/Tomcat 執行期編碼鏈

  1. JSP 原始碼讀取:若頁面有 <%@ page contentType="text/html;charset=GBK" %>,容器依此編碼讀取 .jsp 檔;否則預設 ISO-8859-1。
  2. 編譯為 Servlet:讀取後以 UTF-8 寫入 .java,再用 javac -encoding UTF-8 編譯。
  3. 請求參數解碼:Tomcat 所有參數 (GET/POST) 預設用 ISO-8859-1 解碼(原始碼 HttpUtils.parsePostData、HttpRequestAdapter 可見)。
  4. 回應輸出編碼:response.setContentType("text/html;charset=GBK") 影響 out 寫入器編碼。
  5. <jsp:include> 編碼缺陷:早期 Tomcat 解析器漏掉 encoding 屬性,需自行修補原始碼或避免使用。

實務解決方案比較

方案 A:全站 ISO-8859-1(適合純英文環境或極簡部署)

  • 所有 JavaBean 用 javac -encoding ISO-8859-1 編譯
  • JSP 不加 charset=GBK
  • 伺服器作業系統語系設為英文
  • 缺點:中文參數需手動 new String(param.getBytes("8859_1"), "GBK");檔案上傳分頁極難處理。

方案 B:明確指定 GBK/Big5(推薦中文專案)

<%@ page contentType="text/html;charset=GBK" %>
<% request.setCharacterEncoding("GBK"); %>  // 必須在讀取參數前呼叫
  • JSP、JavaBean、資料庫連線、檔案 I/O 統一用 GBK/Big5
  • Tomcat 5.5+ 可在 server.xml 設定 URIEncoding="GBK" 統一 GET 參數解碼
  • 優點:邏輯清晰、除錯容易、支援 GBK/Big5 切換

方案 C:全站 UTF-8(現代化首選)

  • 所有檔案、資料庫、JSP、Java 原始碼統一 UTF-8
  • 瀏覽器表單送出自動 UTF-8(HTML5 預設)
  • Tomcat server.xml 設定 URIEncoding="UTF-8"
  • 資料庫連線 URL 加 characterEncoding=UTF-8
  • 優點:國際化無痛、無編碼轉換效能損耗、符合現代標準

關鍵檢查清單

  1. JSP 頁面頂端 <%@ page contentType="text/html;charset=UTF-8" %>
  2. web.xml 設定 <filter> CharacterEncodingFilter UTF-8 true </filter>(Spring 提供)
  3. Tomcat server.xml <Connector URIEncoding="UTF-8" />
  4. 資料庫、表格、欄位編碼一致(MySQL: CHARSET=utf8mb4)
  5. JDBC URL: jdbc:mysql:///db?useUnicode=true&characterEncoding=UTF-8
  6. 所有 .java、.jsp、.properties 檔案以 UTF-8 無 BOM 儲存
  7. IDE/編輯器專案編碼設為 UTF-8
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved