Tomcat 預設未指定 Request 編碼時,request.getParameter() 取得的資料為 ISO-8859-1 編碼,導致中文亂碼。
編寫一個 Filter,在請求進入 Servlet/JSP 前統一設定編碼。
package myFilter;
import java.io.IOException;
import javax.servlet.*;
public class ChangeCharsetFilter implements Filter {
protected String encoding = null;
protected FilterConfig filterConfig = null;
public void destroy() {
this.encoding = null;
this.filterConfig = null;
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 僅在未設定編碼時處理,避免重複設定
if (request.getCharacterEncoding() == null) {
String encoding = getEncoding();
if (encoding != null) {
request.setCharacterEncoding(encoding);
}
}
chain.doFilter(request, response); // 繼續過濾鏈
}
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
// 從 web.xml 讀取初始化參數
this.encoding = filterConfig.getInitParameter("encoding");
}
protected String getEncoding() {
return this.encoding;
}
}
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app PUBLIC ...>
<web-app>
<filter>
<filter-name>ChangeCharsetFilter</filter-name>
<filter-class>myFilter.ChangeCharsetFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value> <!-- 或 Big5, GBK -->
</init-param>
</filter>
<filter-mapping>
<filter-name>ChangeCharsetFilter</filter-name>
<url-pattern>/*</url-pattern> <!-- 攔截所有請求 -->
</filter-mapping>
...
</web-app>
request.setCharacterEncoding() 必須在讀取參數前調用(如 getParameter()、getReader())。encoding 參數化,支援 UTF-8、Big5、GBK 等,部署時無需修改代碼。chain.doFilter() 確保過濾鏈繼續執行。同樣重要,可在 Filter 中加入:
response.setContentType("text/html;charset=UTF-8");
response.setCharacterEncoding("UTF-8");
或在 JSP 頁面指令設定:<%@ page contentType="text/html;charset=UTF-8" %>。
Filter 方案為最佳實踐:集中管理、不侵入業務代碼、支援多編碼環境、符合 Servlet 規範。