Tomcat 默認使用 ISO-8859-1 處理 HTTP GET 請求的 URL 編碼。此字符集僅支援單字節字符,導致中文路徑/文件名在下載鏈接、目錄列表中出現亂碼或 404 錯誤。核心解決思路是強制 Tomcat 以 UTF-8 解碼 GET 請求 URL。
$CATALINA_HOME/conf/server.xmlURIEncoding="UTF-8" 屬性<Connector port="8080"
protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8" />
生效條件:修改後必須重啟 Tomcat。
<servlet>
<servlet-name>default</servlet-name>
<servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>0</param-value>
</init-param>
<init-param>
<param-name>listings</param-name>
<param-value>true</param-value> <!-- 改為 true -->
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
$CATALINA_HOME/webapps/cntest/中文目錄/中文文件.txt
訪問 https://localhost:8080/cntest/,若正常顯示中文目錄/文件名並可點擊下載,配置成功。
獲取類加載器資源路徑時,需雙重解碼處理空格與中文:
import java.io.File;
import java.net.URLDecoder;
public class PathUtil {
public static File getResourceFile(String pname) {
try {
// 1. 獲取資源 URL
// 2. getPath() 返回編碼後路徑(空格變 %20,中文變 %E4%B8%AD...)
// 3. URLDecoder.decode 用 UTF-8 解碼
String path = URLDecoder.decode(
Thread.currentThread().getContextClassLoader()
.getResource(pname.replace(".", "/"))
.getPath(),
"UTF-8"
);
return new File(path);
} catch (Exception e) {
throw new RuntimeException("資源路徑解析失敗: " + pname, e);
}
}
}
URIEncoding 屬性request.setCharacterEncoding("UTF-8") 控制,與此配置無關。webapps/中文項目 可能導致部署失敗,上下文路徑建議純 ASCII。proxy_set_header X-Forwarded-For 並確保代理層也用 UTF-8 轉發。Tomcat 中文路徑問題的核心在於 Connector 層面的 URL 解碼編碼。通過 URIEncoding="UTF-8" 一行配置徹底解決 GET 請求中文亂碼,配合 listings=true 可快速驗證。Java 代碼層面記住 URLDecoder.decode(path, "UTF-8") 處理資源路徑,即可覆蓋開發部署全鏈路。