亂碼本質是編碼與解碼方案不一致。JSP 參數傳遞主要三種形式:表單 POST/GET 提交、URL 參數超鏈接、跨窗口 DOM 取值。本文深度剖析前兩者在 Tomcat 容器中的編解碼流程,提供分場景解決方案與全局過濾器最佳實踐。
application/x-www-form-urlencoded,瀏覽器按頁面 charset(如 UTF-8)將中文編碼為 %E4%B8%96%E7%95%8C%E6%9D%AF 格式發送。String val = new String(request.getParameter("username").getBytes("ISO-8859-1"), "UTF-8");
request.setCharacterEncoding("UTF-8")(推薦)需在首次 getParameter 前調用,僅對 POST 有效(API 文檔限制)。
public class EncodingFilter implements Filter {
private String charset;
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) {
req.setCharacterEncoding(charset);
chain.doFilter(req, resp);
}
public void init(FilterConfig cfg) { charset = cfg.getInitParameter("charset"); }
}
web.xml 映射 /*,一次性解決所有 POST 請求亂碼。
Tomcat 解碼 URL 參數使用 server.xml Connector 的 URIEncoding 屬性(預設 ISO-8859-1)。
<Connector port="8080" URIEncoding="UTF-8" />
useBodyEncodingForURI="true"使 request.setCharacterEncoding 同時影響 URL 參數解碼,適合同一實例跑多編碼應用。
發送端:URLEncoder.encode("世界杯", "UTF-8")
接收端:URLDecoder.decode(request.getParameter("param"), "UTF-8")
瀏覽器地址欄顯示中文實為視覺欺騙,實際發送經系統預設編碼(如 GBK→ISO-8859-1)。必須手動編碼:
<a href="./to.jsp?param=<%=URLEncoder.encode("世界杯","UTF-8")%>">Go</a>
接收端同場景二方案三。
| 場景 | 推薦方案 | 備註 |
|---|---|---|
| POST 表單 | 全局過濾器 request.setCharacterEncoding("UTF-8") | 一次配置,全站生效 |
| GET 表單 / URL 參數 | Tomcat URIEncoding="UTF-8" + 過濾器 | 需重啟 Tomcat |
| 超鏈接帶中文 | 手動 URLEncoder/URLDecoder | 最可控,不依賴容器配置 |
pageEncoding="UTF-8" / contentType="text/html;charset=UTF-8"URIEncoding="UTF-8"characterEncoding=UTF-8utf8mb4javac -encoding UTF-8全鏈路統一 UTF-8,是徹底告別亂碼的唯一正道。