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

J2EE 中文亂碼終極解決方案:從編碼原理到全鏈路最佳實踐

     編輯:Java 相關知識

前言:亂碼本質是「編碼/解碼不匹配」

Java 內部統一使用 UTF-16 (char 型別) 處理字元。亂碼產生於 外部資料進入 JVM (解碼) 或 JVM 資料輸出外部 (編碼) 時,雙方約定的字符集不一致。全鏈路統一編碼是唯一正解。

一、 核心字符集知識速查表

字符集別名/特點中文支援適用場景
ISO-8859-1Latin-1, 單字節, 0x00-0xFF❌ 無中文HTTP Header 預設、二進位資料「透傳」中轉
GB2312簡體中文國標, 6763 漢字✅ 簡體舊系統、政府專案強制要求
GBKGB2312 超集, 含繁體/日文, 21003 字✅ 簡繁兼容Windows 國內預設、MySQL 預設、舊專案相容
UTF-8Unicode 變長編碼, 1-4 字節, ASCII 兼容✅ 全語系現代 Web 標準、國際化首選、資料庫/前端/後端統一

鐵律:全棧統一 UTF-8 (資料庫、連線、JVM、前端、容器、框架)。混用編碼必生亂碼。

二、 J2EE 全鏈路編碼傳遞路徑與配置點

瀏覽器 (UTF-8 頁面) 
  → HTTP Request (URL/Body/Header 編碼) 
    → Tomcat Connector (URIEncoding/body encoding) 
      → Servlet Filter (request.setCharacterEncoding) 
        → Controller/Service (Java String UTF-16) 
          → JDBC Driver (connectionCharacterEncoding) 
            → MySQL (utf8mb4) 
              → 回寫路徑反向...

三、 分場景標準化配置清單

1. 前端頁面 (JSP/HTML/Thymeleaf)

<!-- JSP 頁面指令,必須在最頂行 -->
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %>

<!-- HTML5 meta,瀏覽器解碼依據 -->
<meta charset="UTF-8">

<!-- 表單提交指定編碼 (GET 請求 URL 參數編碼由瀏覽器決定,建議全站 POST) -->
<form method="post" accept-charset="UTF-8">...

2. Tomcat 容器層 (server.xml)

<Connector port="8080" protocol="HTTP/1.1"
           URIEncoding="UTF-8" 
           useBodyEncodingForURI="true" />
  • URIEncoding:解決 GET 請求 URL 參數中文亂碼 (Tomcat 8+ 預設即 UTF-8)。
  • useBodyEncodingForURI:讓 POST Body 編碼也套用到 URI 解析 (慎用,可能有副作用)。

3. 全域編碼過濾器 (Spring 專案首選)

web.xml (或 Spring Boot FilterRegistrationBean) 註冊 CharacterEncodingFilter,**必須是 Filter 鏈第一個**:

<filter>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
        <param-name>forceEncoding</param-name> <!-- 強制覆蓋 request/response 編碼 -->
        <param-value>true</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

原理:request.setCharacterEncoding("UTF-8") (僅對 Body 有效) + response.setCharacterEncoding("UTF-8") + response.setContentType("text/html;charset=UTF-8")。

4. Spring MVC 回應輸出

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 確保 JSON/Xml 輸出 UTF-8
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setDefaultCharset(StandardCharsets.UTF_8);
        converters.add(0, converter);
    }
}

5. 資料庫連線 (MySQL 為例)

URL 參數:

jdbc:mysql://host:3306/db?useUnicode=true&characterEncoding=utf8mb4&serverTimezone=Asia/Shanghai

表/庫建立:

CREATE DATABASE mydb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE TABLE t_user (...) DEFAULT CHARSET=utf8mb4;

注意:MySQL utf8 偽 UTF-8 (最多 3 字節),必須用 utf8mb4 存儲 Emoji/生僻字。

6. AJAX / Fetch / Axios 請求

前端發送 JSON 時預設 UTF-8,後端 @RequestBody 自動解碼無需額外配置。
若傳統 application/x-www-form-urlencoded,確保 Content-Type: application/x-www-form-urlencoded; charset=UTF-8。

7. 檔案上傳/下載

  • 上傳:MultipartFilter / StandardServletMultipartResolver 依賴 request 編碼,全域 Filter 已覆蓋。
  • 下載:response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8")) 解決中文檔名亂碼。

四、 疑難雜症診斷流程圖

  1. 確認源頭編碼:瀏覽器 Network 面板查看 Request Payload/Headers 實際位元組。
  2. 驗證容器解碼:Controller 入口打印 request.getCharacterEncoding() 及原始參數。
  3. 檢查資料庫存儲:SELECT HEX(col) FROM table 查看實際位元組,對照 UTF-8/GBK 編碼表。
  4. 排查輸出環節:Response Header Content-Type、瀏覽器檢視編碼選單。

五、 遺留系統 GBK 遷移 UTF-8 策略

  1. 資料庫:ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4; (鎖表風險大,建議雙寫遷移)。
  2. 應用:雙模式運行期,新增 GBK2UTF8Filter 針對特定舊介面轉碼,漸進式切換。
  3. 前端:頁面 charset 統一改 UTF-8,舊頁面若不可改,用 CharacterEncodingFilter forceEncoding=false 避免衝突。

總結:亂碼不是 Bug,是配置缺失。新專案啟動日即鎖定全棧 UTF-8 (utf8mb4),引入 CharacterEncodingFilter、Tomcat URIEncoding、資料庫連線參數三件套,九成九亂碼問題不再出現。

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