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

Tomcat 中文亂碼徹底解決:五大場景完整指南

     編輯:Java 程式設計入門

前言

中文亂碼源於編碼不一致:瀏覽器編碼 → HTTP 傳輸編碼 → 伺服器解碼 → JVM 內部編碼 → 資料庫儲存編碼 → 反向輸出。任一環節錯位即產生亂碼。本文針對 Tomcat 環境,系統梳理五大高發場景與解決方案。

場景一:JSP 頁面直接輸出中文亂碼

現象:JSP 檔案儲存為 UTF-8/GBK,瀏覽器顯示亂碼。
原因:JSP 編譯為 Servlet 時,若未指定 pageEncoding,容器預設用 ISO-8859-1 讀取源檔。
解決:頁面頂端第一行宣告:

<%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="UTF-8" %>
  • contentType:設定 HTTP Response 標頭 Content-Type: text/html;charset=UTF-8,告訴瀏覽器以 UTF-8 解碼。
  • pageEncoding:告訴 JSP 編譯器源檔編碼為 UTF-8。
  • 建議統一專案為 UTF-8 (IDE、檔案儲存、資料庫、前端皆 UTF-8),避免多編碼共存。

場景二:Request 取得參數 (POST) 亂碼

現象:request.getParameter("name") 取得中文參數為亂碼。
原因:Tomcat 預設用 ISO-8859-1 解碼 Request Body。
解決:配置全域 Filter (放在所有 Filter 鏈最前):

@WebFilter("/*")
public class EncodingFilter implements Filter {
    @Override
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
            throws IOException, ServletException {
        req.setCharacterEncoding("UTF-8"); // 必須在 getParameter() 前呼叫
        resp.setCharacterEncoding("UTF-8");
        chain.doFilter(req, resp);
    }
}

web.xml 註冊 (若不用註解):

<filter>
    <filter-name>EncodingFilter</filter-name>
    <filter-class>com.example.EncodingFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>EncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

場景三:GET 請求參數亂碼 (Filter 無效)

現象:POST 正常,GET 亂碼。
原因:GET 參數在 URL Query String,屬於 HTTP 標頭範圍,request.setCharacterEncoding() 不影響標頭解碼。Tomcat 解碼 URL 使用 URIEncoding 設定。
解決:修改 $CATALINA_HOME/conf/server.xml,在 `` 加入 URIEncoding="UTF-8":

<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443"
           URIEncoding="UTF-8"
           useBodyEncodingForURI="true" />
  • useBodyEncodingForURI="true":若未設定 URIEncoding,回退使用 request.getCharacterEncoding() (即 Filter 設定值),雙重保險。
  • 重啟 Tomcat 生效。

場景四:JSP 按鈕/標籤文字亂碼 — 使用資源包

現象:JSP 中寫死中文標籤 (如 ``),換環境或編譯亂碼。
最佳實務:程式碼與內容分離,使用 `` (Struts) 或 `` (JSTL) + ResourceBundle。

步驟

  1. 建立基礎屬性檔 ApplicationResources.properties (ISO-8859-1 編碼):
    button.search=查詢
    label.username=用戶名
    
  2. 用 native2ascii 轉換為 Unicode 轉義檔 ApplicationResources_zh_TW.properties:
    native2ascii -encoding UTF-8 ApplicationResources.properties ApplicationResources_zh_TW.properties
    
    產生:button.search=\u67e5\u8a22
  3. 放置於 WEB-INF/classes/。
  4. struts-config.xml 配置:<message-resources parameter="ApplicationResources" />
  5. JSP 使用:<bean:message key="button.search" /> 或 <fmt:message key="button.search" />

優點:支援多國語系 (i18n)、編碼安全、內容維護集中化。

場景五:資料庫讀寫中文亂碼

JDBC 直連

URL 加入參數:

jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull

資料源

Tomcat `` 配置:

<parameter>
    <name>url</name>
    <value><![CDATA[jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8]]></value>
</parameter>
<parameter>
    <name>driverClassName</name>
    <value>com.mysql.cj.jdbc.Driver</value>
</parameter>

注意:MySQL 8.0+ 驅動類為 com.mysql.cj.jdbc.Driver,舊版為 com.mysql.jdbc.Driver。

綜合檢查清單

層級檢查項目標準值
IDE/編輯器檔案編碼UTF-8
JSPpageEncoding / contentTypeUTF-8
Servlet/Filterrequest/response.setCharacterEncodingUTF-8
Tomcat ConnectorURIEncoding / useBodyEncodingForURIUTF-8 / true
資料庫連線characterEncoding / connectionCollationUTF-8 / utf8mb4_general_ci
資料表/欄位CHARSET / COLLATEutf8mb4 / utf8mb4_general_ci
前端 HTML<meta charset="UTF-8">UTF-8
JS/CSS 檔案檔案編碼UTF-8

結語

中文亂碼本質是編碼協議不匹配。建立全鏈路 UTF-8 標準,配合 Filter 統一 Request/Response、Tomcat `URIEncoding` 解決 GET、資源包隔離頁面文字、JDBC URL 明確指定編碼,即可徹底根治。避免在代碼中手動 `new String(bytes, "ISO-8859-1")` 轉碼,那是治標不治本的惡習。

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