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

Java 亂碼問題根因分析與解決方案全攻略

     編輯:Java 相關知識

亂碼是軟體開發中普遍且棘手的問題。本文從編碼本質出發,系統梳理亂碼產生的兩大核心原因,並提供針對性解決方案。

核心原因一:軟體預設編碼不一致

記事本:無編碼概念

記事本不儲存編碼資訊,純位元組存取,「寫入什麼即顯示什麼」。這也是為何它常被作為編碼診斷的基準工具。

Excel:預設 ASCII/ANSI

Excel 預設使用系統 ANSI 編碼(中文環境為 GBK/CP936)。若程式以 UTF-8 寫入,Excel 以 ANSI 讀取,必然產生亂碼。

核心原因二:寫入與讀取編碼不匹配

場景 1:網頁瀏覽亂碼

伺服器回傳 UTF-8 頁面,但頁面未宣告 <meta charset="UTF-8">,瀏覽器回退預設編碼(如 GBK)解碼 → 亂碼。
解決:HTTP 標頭 Content-Type: text/html; charset=UTF-8 + 頁面 meta 標籤雙重保障。

場景 2:檔案下載檔名亂碼

瀏覽器下載時依預設編碼(GB 系列)解析 Content-Disposition 標頭中的檔名,而後端常以 UTF-8 編碼。
解決:檔名手動編碼為 ISO-8859-1 或 RFC 5987 格式:

// Spring MVC 範例
String fileName = URLEncoder.encode("中文檔名.csv", "UTF-8").replace("+", "%20");
response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + fileName);

場景 3:CSV 匯出 Excel 開啟亂碼

Excel 預設以 ANSI 開啟 CSV,但支援 UTF-8 **帶 BOM (Byte Order Mark)** 自動識別。
解決:寫入 UTF-8 BOM 標記 (EF BB BF):

OutputStreamWriter osw = new OutputStreamWriter(response.getOutputStream(), "UTF-8");
response.setHeader("Content-Disposition", "attachment; filename=test.csv");
// 寫入 BOM
osw.write(new byte[]{(byte)0xEF, (byte)0xBB, (byte)0xBF});
osw.write(csvContent);
osw.flush();

通用防禦策略

  1. 全鏈路統一 UTF-8:資料庫、連線池、JVM (-Dfile.encoding=UTF-8)、IDE、建構工具
  2. 明確指定編碼:所有 getBytes()、new String(bytes)、IO 流建構必須顯式傳編碼參數
  3. 資料庫連線參數:MySQL useUnicode=true&characterEncoding=UTF-8
  4. 前端宣告:HTML meta、AJAX contentType、Form accept-charset
  5. 日誌記錄原始位元組:除錯時輸出十六進位位元組而非字串

編碼轉換工具類

public final class CharsetUtil {
    public static String convert(String input, String fromCharset, String toCharset) {
        try {
            return new String(input.getBytes(fromCharset), toCharset);
        } catch (UnsupportedEncodingException e) {
            throw new IllegalArgumentException(e);
        }
    }
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved