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

Java 中文編碼問題深度分析與解決方案

     編輯:Java 相關知識

前言

Java 程式開發中,中文亂碼是令開發者頭痛的常見問題。Java 內部採用 Unicode (UTF-16) 編碼,而中文環境常用 Big5、GB2312/GBK、UTF-8 等編碼。編碼不匹配會導致資料庫儲存、檔案讀寫、網頁顯示、Console 輸出等環節產生亂碼。本文從編碼基礎出發,系統分析 Java 中文處理全鏈路,提供實戰解決方案。

中文編碼基礎知識

編碼說明適用範圍
ASCII1 Byte,0x00-0x7F英文字元
Big52 Bytes,高位元為 1繁體中文(台灣、香港)
GB2312/GBK2 Bytes,高位元為 1簡體中文(大陸、新加坡)
Unicode (UTF-16)2-4 Bytes 固定長度Java 內部字元表示
UTF-81-4 Bytes 變長網頁、檔案儲存、傳輸標準

Java String 內部為 UTF-16。"蘋果".length() == 2(字元數),但 getBytes("UTF-8").length == 6(位元組數)。

Java 中文處理全鏈路與潛在斷點

  1. 原始碼編譯:javac -encoding UTF-8 指定原始檔編碼,避免 Linux (預設 ISO-8859-1) 編譯亂碼。
  2. 類別檔案載入:JRE 國際版支援多語言,確保生產環境安裝正確版本。
  3. 運行時編碼轉換:System.getProperty("file.encoding") 影響預設編碼,Windows 通常為 Cp1252/GBK,Linux 為 UTF-8。
  4. I/O 操作:InputStreamReader/OutputStreamWriter 必須顯式指定編碼,切勿依賴預設值。
  5. 資料庫交互:JDBC URL 加入 characterEncoding=UTF-8,連線池層面統一設定。
  6. Web 輸出:JSP `<%@ page contentType="text/html;charset=UTF-8" %>`,Servlet `response.setCharacterEncoding("UTF-8")`。
  7. 瀏覽器顯示:HTML ``,確保前後端編碼一致。

核心解決方案:統一採用 UTF-8 全鏈路

1. 原始碼與編譯

// 建議所有 .java 檔案儲存為 UTF-8
javac -encoding UTF-8 MyClass.java

2. 檔案讀寫最佳實務

// 讀取 GBK 編碼檔案
try (BufferedReader br = new BufferedReader(
        new InputStreamReader(new FileInputStream("gbk.txt"), "GBK"))) {
    String line;
    while ((line = br.readLine()) != null) { /* 處理 */ }
}

// 寫入 UTF-8 檔案
try (BufferedWriter bw = new BufferedWriter(
        new OutputStreamWriter(new FileOutputStream("utf8.txt"), "UTF-8"))) {
    bw.write("內容");
}

3. 網頁與 Servlet 統一編碼

// JSP 頁面指令
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %>

// Servlet 設定
request.setCharacterEncoding("UTF-8");  // 必須在 getParameter() 前呼叫
response.setContentType("text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");

4. 資料庫連線設定

// MySQL 範例
String url = "jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Taipei";
// PostgreSQL
String url = "jdbc:postgresql://localhost:5432/db?charSet=UTF-8";
// Oracle (JDBC 12.1+ 自動處理,舊版需 orai18n.jar)
Properties props = new Properties();
props.setProperty("user", "usr");
props.setProperty("password", "pwd");
props.setProperty("defaultNChar", "true"); // 國字集支援

5. 參數編碼修復工具方法(舊專案救援)

/**
 * 修復 ISO-8859-1 錯誤解碼的中文參數
 * 適用:Tomcat 預設 ISO-8859-1 解碼 GET 參數,實際為 UTF-8/GBK
 */
public static String fixEncoding(String param, String actualEncoding) {
    if (param == null) return null;
    try {
        return new String(param.getBytes("ISO-8859-1"), actualEncoding);
    } catch (UnsupportedEncodingException e) {
        return param; // 回退原值
    }
}

// 使用範例
String fixed = fixEncoding(request.getParameter("keyword"), "UTF-8");

常見問題診斷清單

  • ☐ 專案原始碼檔案編碼是否統一為 UTF-8?
  • ☐ javac / IDE 建置編碼設定正確?
  • ☐ 伺服器 file.encoding 系統屬性是否符合預期?
  • ☐ 所有 I/O、JDBC、Web 層是否顯式指定編碼?
  • ☐ 前端 HTML `` 與後端 Content-Type 一致?
  • ☐ 資料庫表欄位、連線字串編碼設定正確?

歷史遺留專案遷移建議

  1. 新程式碼全面採用 UTF-8。
  2. 舊模組邊界加入編碼轉換適配器(如上 fixEncoding)。
  3. 資料庫欄位逐步轉為 utf8mb4 (MySQL) 或 NVARCHAR (SQL Server/Oracle)。
  4. 建立整合測試驗證中文圓周率「圓周率3.14159」等邊界字元。

結語

中文亂碼本質是「編碼不一致」。現代 Java 開發應建立「UTF-8 全鏈路」標準:原始碼、編譯、運行時、I/O、資料庫、Web 輸出、前端顯示全環節統一 UTF-8。舊系統可透過邊界轉換器漸進式遷移。掌握 Charset、Reader/Writer、JDBC 連線參數、Servlet 過濾器編碼設定等核心 API,即可從根本解決亂碼困擾。

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