Java 內部 UTF-16,I/O 邊界發生編碼轉換。亂碼 = 讀取編碼 ≠ 寫入編碼,或 聲明編碼 ≠ 實際編碼。三大高發戰場:JSP/Servlet、JDBC、系統層面。
server.xml <Connector URIEncoding="UTF-8"/> 確認。Content-Type charset 解碼。request.setCharacterEncoding("UTF-8") 必須在首次讀取參數前調用(Filter 中攔截最佳)。// 方式一:page 指令(JSP 頂部)
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
// 方式二:Servlet 代碼
response.setContentType("text/html; charset=UTF-8");
response.setCharacterEncoding("UTF-8"); // 等同於上一行
// 方式三:HTML meta(瀏覽器兜底識別)
<meta charset="UTF-8">
鐵律:pageEncoding(源文件編碼)= charset(輸出編碼)= request.setCharacterEncoding(輸入編碼)= 數據庫連接編碼 = 文件/日誌編碼 = 全鏈路 UTF-8。
// MySQL 8.0+ (Con/J 8.0+)
jdbc:mysql://host:3306/db?characterEncoding=utf8&useUnicode=true&serverTimezone=Asia/Shanghai
// Oracle
jdbc:oracle:thin:@host:1521:sid
// 驅動默認按 NLS_LANG 環境變量或 JVM file.encoding,建議顯式設置
System.setProperty("oracle.jdbc.defaultNChar", "true");
// 寫入:PreparedStatement 自動按連接編碼轉換
ps.setString(1, "中文"); // 推薦
// 或顯式字節
ps.setBytes(1, "中文".getBytes(StandardCharsets.UTF_8));
// 讀取:getString 自動解碼
String val = rs.getString("col"); // 推薦
// 歷史驅動可能需手動轉碼(極少見)
// String val = new String(rs.getBytes("col"), "ISO-8859-1"); // 反模式
驅動差異大:i-net UNA 免轉碼、舊版 jTDS 需手動、PostgreSQL 默認 UTF-8。**上線前必測該驅動中文存取**。
// 顯式指定編碼,禁用平台默認
Files.readString(path, StandardCharsets.UTF_8);
Files.writeString(path, content, StandardCharsets.UTF_8);
// 歷史代碼
new String(bytes, "GBK"); // 明確源編碼
new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
-Dfile.encoding=UTF-8
// 影響:Charset.defaultCharset()、InputStreamReader/OutputStreamWriter 無參構造器
// 風險:第三方庫可能依賴平台默認編碼,全局修改可能引發新亂碼
// 建議:代碼中顯式指定編碼,不依賴 file.encoding
<!-- Logback -->
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<encoder>
<charset>UTF-8</charset>
</encoder>
</appender>
new String(bytes, "GBK"))。ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4(MySQL)。<meta charset="UTF-8">,AJAX 請求 contentType: "application/json; charset=UTF-8"。pageEncoding = charset = UTF-8。request.setCharacterEncoding("UTF-8")。response.setCharacterEncoding("UTF-8")。characterEncoding=utf8(或對應參數)。StandardCharsets.UTF_8。<meta charset="UTF-8">,AJAX/表單提交編碼一致。亂碼治理無捷徑,只有「全鏈路顯式、統一 UTF-8、自動化驗證」。把編碼當作接口契約的一部分,寫進代碼規範、CI 檢查、架構決策記錄(ADR)裡。