在 Java Web 開發中,中文亂碼是困擾開發者的經典問題。本文系統梳理 POST 與 GET 請求的編碼差異,提供三種實用解決方案,助你徹底告別亂碼困擾。
HTTP 協議規定 URL 只能包含 ASCII 字元,中文等非 ASCII 字元必須經過編碼傳輸。POST 請求參數在請求體中,可透過設定字元編碼解決;GET 請求參數附在 URL 後,編碼方式由瀏覽器與伺服器協商決定,處理較為複雜。
在 Servlet 或 Filter 中於讀取參數前設定:
request.setCharacterEncoding("UTF-8");
注意:必須在呼叫 getParameter() 之前設定,否則無效。建議在 Filter 中統一處理,確保所有 POST 請求生效。
針對 GET 請求,可手動解析查詢字串並解碼:
// 獲取原始查詢字串
String queryString = request.getQueryString();
// 使用 URLDecoder 以 UTF-8 解碼
String decodedString = java.net.URLDecoder.decode(queryString, "UTF-8");
// 解析參數
String[] paramPairs = decodedString.split("&");
for (String pair : paramPairs) {
String[] keyValue = pair.split("=");
String paramName = keyValue[0];
String paramValue = keyValue.length > 1 ? keyValue[1] : "";
// 此處 paramValue 即為正確解碼後的中文值
}
利用 Servlet 容器預設以 ISO-8859-1 解碼 URL 參數的特性,反向轉換:
// 獲取容器解碼後的參數值(實為錯誤解碼)
String rawValue = request.getParameter("name");
// 將錯誤解碼的字串按 ISO-8859-1 還原為位元組陣列
byte[] bytes = rawValue.getBytes("ISO-8859-1");
// 以正確編碼 UTF-8 重新解析位元組
String correctValue = new String(bytes, "UTF-8");
@WebFilter("/*")
public class EncodingFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
// 統一設定請求/回應編碼
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
// GET 請求特殊處理
if ("GET".equalsIgnoreCase(request.getMethod())) {
request = new HttpServletRequestWrapper(request) {
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
if (value == null) return null;
try {
return new String(value.getBytes("ISO-8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e) {
return value;
}
}
};
}
chain.doFilter(request, response);
}
}
在 server.xml 的 Connector 中設定:
<Connector port="8080" protocol="HTTP/1.1"
URIEncoding="UTF-8"
useBodyEncodingForURI="true" />
URIEncoding="UTF-8":指定 URL 解碼編碼useBodyEncodingForURI="true":若請求體已設定編碼,則 URL 也使用該編碼在 web.xml 註冊 CharacterEncodingFilter:
<filter>
<filter-name>encodingFilter</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>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
MultipartFilter 或 Spring 的 MultipartResolver 設定編碼redirect: 時中文參數需手動 URLEncoder.encode掌握編碼原理,配合容器配置與 Filter 統一處理,即可從根源解決 Java Web 中文亂碼問題,避免在業務代碼中散落各種解碼邏輯。