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

Hibernate + Spring + Struts + MySQL 亂碼終極解決方案:全鏈路 UTF-8 統一實戰

     編輯:Java 相關知識

亂碼根因:編碼鏈路任一環節不一致

數據流向:瀏覽器 → Tomcat → Filter → Servlet/Action → Service → DAO → Hibernate → JDBC → MySQL。任一節點編碼設置缺失或衝突,即導致亂碼。本文提供「零配置遺漏」的全鏈路 UTF-8 統一方案。

第一層:數據庫服務端

MySQL 配置 (my.cnf / my.ini)

[mysqld]
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'

[client]
default-character-set=utf8mb4

[mysql]
default-character-set=utf8mb4
  • utf8mb4 支持 Emoji 及補充字符,utf8 僅支持 BMP 平面(3 字節),生產環境強制 utf8mb4。
  • 修改後 重啟 MySQL,並重建資料庫/表:ALTER DATABASE db CHARACTER SET utf8mb4; ALTER TABLE t CONVERT TO CHARACTER SET utf8mb4;

建表/建庫顯式指定

CREATE DATABASE mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE TABLE user (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

第二層:JDBC 連接串

jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8mb4&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
  • useUnicode=true&characterEncoding=utf8mb4 強制驅動以 UTF-8 收發。
  • MySQL 8.0+ 驅動默認已支持 utf8mb4,但顯式聲明更安全。

第三層:Hibernate 配置

hibernate.cfg.xml / persistence.xml

<property name="hibernate.connection.CharSet">utf8mb4</property>
<property name="hibernate.connection.characterEncoding">utf8mb4</property>
<property name="hibernate.connection.useUnicode">true</property>

第四層:Web 容器

Tomcat server.xml (Connector)

<Connector port="8080" protocol="HTTP/1.1"
           URIEncoding="UTF-8" 
           useBodyEncodingForURI="true" />
  • URIEncoding 解決 GET 請求參數中文亂碼。
  • useBodyEncodingForURI 讓 POST 請求體編碼與 request.setCharacterEncoding 一致。

第五層:統一編碼過濾器(核心攔截點)

web.xml 配置(必須是第一個 Filter)

<filter>
    <filter-name>CharacterEncodingFilter</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>
        <param-value>true</param-value> <!-- 強制覆蓋 request/response 編碼 -->
    </init-param>
</filter>
<filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

原理: Spring 提供的 CharacterEncodingFilter 在 doFilter 中調用 request.setCharacterEncoding(encoding) 和 response.setCharacterEncoding(encoding),forceEncoding=true 確保即使請求已讀取也強制重置。

若無 Spring 依賴,自定義 Filter

public class EncodingFilter implements Filter {
    private String encoding = "UTF-8";
    private boolean force = true;

    @Override
    public void init(FilterConfig config) {
        encoding = config.getInitParameter("encoding");
        force = Boolean.parseBoolean(config.getInitParameter("forceEncoding"));
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) {
        if (force || req.getCharacterEncoding() == null) {
            req.setCharacterEncoding(encoding);
            resp.setCharacterEncoding(encoding);
        }
        chain.doFilter(req, resp);
    }
    @Override public void destroy() {}
}

第六層:JSP 頁面聲明

<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
</head>
  • pageEncoding:JSP 文件本身的保存編碼(IDE 必須同步設置)。
  • contentType:響應 Headers 的 Content-Type。
  • <meta charset>:瀏覽器渲染參考。

第七層:前端表單提交

<form action="/user/save" method="post" accept-charset="UTF-8">
    <input name="name" />
</form>

accept-charset 明確告知瀏覽器以 UTF-8 編碼表單數據。

驗證清單:一鍵排查

層級檢查點驗證命令/現象
DB庫/表/列編碼SHOW CREATE TABLE user; 顯示 utf8mb4
JDBC連接串參數日誌顯示 SET NAMES utf8mb4
Hibernate配置屬性啟動日誌無編碼警告
TomcatConnector 設置GET 中文參數正常
Filter順序第一、force=truePOST 中文參數正常
JSPpageEncoding=UTF-8頁面顯示正常
前端meta charset、accept-charset表單提交無亂碼

常見誤區

  • ❌ 只在 JSP 加 pageEncoding,不配 Filter → POST 亂碼。
  • ❌ MySQL 用 utf8,插入 Emoji 報錯 Incorrect string value → 必須 utf8mb4。
  • ❌ Filter 順序靠後,被其他 Filter 先讀取請求體 → 設置無效。
  • ❌ IDE 保存文件為 GBK,但聲明 UTF-8 → 編譯報錯或運行亂碼。

總結

亂碼本質是 「編碼協議不匹配」。建立「UTF-8 全鏈路」標準:數據庫 utf8mb4 → JDBC 顯式編碼 → Tomcat URIEncoding → Spring CharacterEncodingFilter(force=true) → JSP pageEncoding=UTF-8 → 前端 meta/form charset。一次配置,永久解決。新項目啟動即納入規範,老項目按清單逐層補齊,杜絕亂碼反彈。

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