虛擬主機環境下亂碼問題高發,原因在於開發環境與生產環境 Tomcat 配置、JDK 版本、數據庫編碼不一致。本文按「數據流向」劃分三大場景,給出針對性解決方案與驗證方法。
現象:頁面顯示正常,但提交中文後入庫/顯示為亂碼(如 ???、涓婂竷)。
根因:Tomcat 默認使用 ISO-8859-1 解碼 POST 請求體。
方案 A:全局 Filter(推薦,一次配置全站生效)
@WebFilter("/*")
public class EncodingFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
req.setCharacterEncoding("UTF-8");
res.setCharacterEncoding("UTF-8");
chain.doFilter(req, res);
}
}
方案 B:Tomcat server.xml 強制指定(僅影響 GET 請求 URI 解碼,POST 無效)
<Connector port="8080" protocol="HTTP/1.1"
URIEncoding="UTF-8" /> <!-- GET 參數解碼 -->
驗證:Filter 中打印 req.getParameter("name") 確認解碼正確。
判斷方法:用客戶端工具(Navicat、DBeaver、MySQL Workbench)連接數據庫,**嘗試切換連接編碼**(GBK、UTF-8、Latin1)查看同一條記錄:
修復歷史數據(MySQL 示例):
-- 假設錯誤寫入為 Latin1 實際為 UTF-8 字節
UPDATE t_user SET name = CONVERT(CAST(CONVERT(name USING latin1) AS BINARY) USING utf8mb4);
預防:建表/建庫顯式指定 CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci。
現象:數據庫客戶端看正常,Java 讀出變亂碼。
核心修正:JDBC URL 顯式指定字符集
# MySQL 8.0+ (推薦)
jdbc:mysql://host:3306/db?characterEncoding=UTF-8&useUnicode=true&serverTimezone=Asia/Shanghai
# MySQL 5.x
jdbc:mysql://host:3306/db?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true
# PostgreSQL
jdbc:postgresql://host:5432/db?charSet=UTF-8
# Oracle (需驅動 12.1+)
jdbc:oracle:thin:@host:1521:SID?oracle.jdbc.defaultNChar=true
關鍵點:
& 實體轉義(XML 配置文件除外),Java Properties/代碼中直接寫 &。hibernate.connection.url 同理,若用 XML 配置需寫 &。characterEncoding 參數,升級驅動。| 層級 | 配置項 | 標準值 |
|---|---|---|
| 瀏覽器 | <meta charset="UTF-8"> | UTF-8 |
| JSP/HTML | pageEncoding / contentType | UTF-8 |
| Servlet/Filter | request/response.setCharacterEncoding | UTF-8 |
| Tomcat | Connector URIEncoding | UTF-8 |
| JDBC URL | characterEncoding / useUnicode | UTF-8 / true |
| 數據庫 | 建庫/建表 CHARSET | utf8mb4 |
| 數據庫連接 | 客戶端工具連接編碼 | UTF-8 |
# server.xml Host 節點內
<Valve className="org.apache.catalina.valves.AccessLogValve"
directory="logs" prefix="access" suffix=".log"
pattern="%h %l %u %t "%r" %s %b %D %{User-Agent}i" />
配合 log4j2 記錄 request.getParameterMap(),可精確定位編碼在哪一環節發生偏移。
亂碼本質是「編碼不一致」。建立「全鏈路 UTF-8」標準,配合 Filter 全局攔截、JDBC URL 顯式聲明、數據庫 utf8mb4,99% 的虛擬主機亂碼問題可徹底根治。