登入表單輸入中文「張三」,Action 接收到卻變亂碼,導致驗證失敗。

根因:瀏覽器以 UTF-8/Big5 送出,Tomcat 預設用 ISO-8859-1 解碼,編碼不一致。
package util;
public class Encoding {
public static String isoToGbk(String src) {
try {
return new String(src.getBytes("ISO-8859-1"), "GBK");
} catch (Exception e) {
e.printStackTrace();
return src;
}
}
}
Action 中每欄位呼叫 Encoding.isoToGbk(username)。缺點:易漏寫、維護困難、耦合業務邏輯。
覆寫 processPreprocess,在所有 Action 前統一設定編碼:
package servlets;
import javax.servlet.http.*;
import org.apache.struts.action.RequestProcessor;
public class EncodingHandler extends RequestProcessor {
@Override
public boolean processPreprocess(HttpServletRequest req, HttpServletResponse res) {
try {
req.setCharacterEncoding("GBK"); // 或 UTF-8
System.out.println("請求編碼已設定");
} catch (Exception e) { e.printStackTrace(); }
return true;
}
}
struts-config.xml 註冊:
<controller processorClass="servlets.EncodingHandler" />
優點:一次設定全域生效。缺點:綁定 Struts,遷移框架需重寫。
package filter;
import javax.servlet.*;
import java.io.IOException;
public class EncodingFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
req.setCharacterEncoding("UTF-8"); // 建議統一 UTF-8
chain.doFilter(req, res);
}
@Override public void init(FilterConfig cfg) {}
@Override public void destroy() {}
}
web.xml 註冊:
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
優點:框架無關、攔截所有請求、可針對特定 URL 排除、支援回應編碼設定。
| 方案 | 適用場景 | 推薦度 |
|---|---|---|
| 手動轉碼 | 極小專案、快速測試 | ⭐ |
| RequestProcessor | 純 Struts 1 專案、不想動 web.xml | ⭐⭐ |
| Filter | 所有 Java Web 專案(含 Spring MVC、Servlet) | ⭐⭐⭐⭐⭐ |
現代專案請直接使用 Filter + UTF-8,並確保資料庫、JSP、JS 檔案編碼一致。