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

解決 Tomcat GET 請求中文亂碼:從 Filter 到 Connector 徹底根治

     編輯:Java 相關知識

Tomcat 處理 GET/POST 請求編碼的機制不同,導致 POST 可通過 Filter 解決,而 GET 需修改 Connector 配置。本文系統梳理亂碼產生原因、分層解決方案與生產環境最佳實踐。

亂碼根因分析

POST 請求:請求體編碼

  • 瀏覽器按 Content-Type: application/x-www-form-urlencoded; charset=UTF-8 編碼請求體
  • Tomcat 默認用 ISO-8859-1 解碼 → 亂碼
  • Filter 可在 request.getParameter() 前設置 request.setCharacterEncoding("UTF-8")

GET 請求:URL 編碼

  • 參數在 URL 查詢字符串:/search?q=中文
  • 瀏覽器按頁面編碼 (或 UTF-8) 對查詢字符串 URL 編碼:%E4%B8%AD%E6%96%87
  • Tomcat 解析 URL 時 用 ISO-8859-1 解碼查詢字符串 → 亂碼
  • Filter 無法攔截 URL 解析階段 (發生在 Filter 鏈之前)

分層解決方案

第 1 層:Spring CharacterEncodingFilter (解決 POST)

<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 Boot 自動配置:spring.mvc.servlet.encoding.enabled=true (默認)、spring.mvc.servlet.encoding.charset=UTF-8、spring.mvc.servlet.encoding.force=true

第 2 層:Tomcat Connector 配置 (解決 GET)

方案 A:URIEncoding (推薦,Tomcat 7+)

<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443"
           URIEncoding="UTF-8" />

方案 B:useBodyEncodingForURI (舊版本兼容)

<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443"
           useBodyEncodingForURI="true" />

差異:URIEncoding 直接指定 URL 解碼編碼;useBodyEncodingForURI 使用請求體編碼 (由 Filter 設置) 解碼 URL。推薦 URIEncoding,更顯式、不依賴 Filter 順序。

第 3 層:Spring Boot 內嵌 Tomcat 配置 (無需修改 server.xml)

application.yml

server:
  tomcat:
    uri-encoding: UTF-8
    # 或 Spring Boot 2.6+ 標準屬性
  servlet:
    encoding:
      charset: UTF-8
      force: true
      enabled: true

Java Config (程式化)

{ connector.setURIEncoding("UTF-8"); // connector.setUseBodyEncodingForURI(true); }); return factory; }

Eclipse/IDEA 開發環境陷阱

現象

修改 server.xml 後重啟項目,配置被重置為默認值。

原因

IDE 使用工作空間元數據管理 Tomcat 配置,而非安裝目錄下的 server.xml。

解決

  • Eclipse:Servers 視圖 → 雙擊 Tomcat → Overview → Server Locations → "Use Tomcat installation" → 修改安裝目錄 conf/server.xml
  • IDEA:Run Configuration → Application Server → Tomcat → Configure → 取消 "Use workspace metadata" → 直接編輯安裝目錄 conf/server.xml
  • Spring Boot 開發:直接用 application.yml 配置,無需碰 server.xml

AJAX GET 請求特殊情況

// 前端 jQuery
$.get("/api/search", {q: "中文"}, function(data) {...});

// 即使設置了 URIEncoding="UTF-8",若前端未正確編碼仍會亂碼
// 確保前端:
// 1. 頁面 
// 2. $.ajax 默認 UTF-8,無需額外設置
// 3. 若手動拼接 URL:encodeURIComponent("中文") → "%E4%B8%AD%E6%96%87"

生產環境完整配置清單

# 1. Spring Boot 應用層
spring:
  mvc:
    servlet:
      encoding:
        charset: UTF-8
        force: true
        enabled: true

# 2. 內嵌 Tomcat 連接器
server:
  tomcat:
    uri-encoding: UTF-8
    max-http-header-size: 8192  # 防止長 URL 截斷

# 3. 反向代理 (Nginx) - 關鍵!
# Nginx 必須透傳原始 URL 編碼
location / {
    proxy_pass https://backend;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    # 關鍵:不解碼、不重新編碼
    proxy_pass_request_headers on;
}

# 4. 數據庫連接
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC

# 5. 頁面/響應
# Spring Boot 默認 response.setContentType("text/html;charset=UTF-8")
# JSP: <%@ page pageEncoding="UTF-8" contentType="text/html;charset=UTF-8" %>
# Thymeleaf: spring.thymeleaf.encoding=UTF-8

驗證清單

  1. POST 表單提交中文 → 後端正確接收
  2. GET 請求 /search?q=中文 → 後端正確接收
  3. AJAX GET/POST 中文參數 → 正確接收
  4. 數據庫存讀中文 → 正常
  5. 響應頁面/JSON 中文 → 瀏覽器正確顯示
  6. 經 Nginx 代理後上述全部正常

總結

Tomcat GET 亂碼本質是 URL 解析階段編碼不匹配。解決路徑:Spring Filter 處理 POST → Tomcat Connector URIEncoding 處理 GET → Spring Boot application.yml 統一配置 → Nginx 透傳原始編碼。開發環境切記 IDE 管理 Tomcat 配置的特殊性,生產環境建議全鏈路 UTF-8 統一,徹底告別亂碼。

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