URL 中文亂碼本質是「瀏覽器編碼 → 服務端解碼」不一致導致的字節序列錯誤解讀。涉及三個關鍵環節:
request.getParameter() 直接使用容器解碼結果。強制指定 URI 解碼字符集,一勞永逸。
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
URIEncoding="UTF-8"
useBodyEncodingForURI="true" />
URIEncoding="UTF-8":告訴 Tomcat 用 UTF-8 解碼 URL (含查詢字符串)。useBodyEncodingForURI="true":若請求體有編碼 (POST),則用該編碼解碼 URI (兼容舊應用)。@WebFilter("/*")
public class EncodingFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=UTF-8");
chain.doFilter(req, resp);
}
}
作用:覆蓋 POST 請求體編碼,確保 request.getParameter() 正確讀取 Body 參數。
若無法修改容器配置 (如虛擬主機),可在代碼中手動修正:
// GET 參數修正
String raw = request.getParameter("name"); // 已被 ISO-8859-1 錯誤解碼
String correct = new String(raw.getBytes("ISO-8859-1"), "UTF-8");
// 通用工具方法
public static String decodeParam(String param, HttpServletRequest request) {
if (param == null) return null;
String enc = request.getCharacterEncoding();
if (enc == null) enc = "ISO-8859-1";
try {
return new String(param.getBytes(enc), "UTF-8");
} catch (UnsupportedEncodingException e) {
return param; // 兜底
}
}
// 錯誤:直接拼接中文
location.href = "/search?q=關鍵詞"; // 瀏覽器可能用 GBK 編碼
// 正確:encodeURIComponent 強制 UTF-8 編碼
location.href = "/search?q=" + encodeURIComponent("關鍵詞");
// 產生: /search?q=%E9%97%9C%E9%8D%B5%E8%A9%9E
// 表單提交
<form action="/search" method="get" accept-charset="UTF-8">
<input name="q" />
</form>
Content-Type: application/x-www-form-urlencoded; charset=UTF-8 決定。request.setCharacterEncoding("UTF-8") 在讀取參數前執行,POST 中文通常無亂碼。request.getPart()) 支援編碼設置。Spring MVC 中 @PathVariable 同樣受 URIEncoding 影響。若 Tomcat 未配置,需在 web.xml 添加 CharacterEncodingFilter 並設置 forceEncoding=true。
<meta charset="UTF-8">。server.xml Connector 是否有 URIEncoding="UTF-8"。proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 一般不影響編碼)。「容器配置 URIEncoding + 過濾器統一編碼 + 前端 encodeURIComponent」三位一體,徹底根治 URL 中文亂碼。原則:全鏈路 UTF-8,任何環節不允許出現 GBK/ISO-8859-1。新項目啟動即配置,老項目補全 Filter 與 server.xml,亂碼問題將不再困擾。