瀏覽器發送請求參數預設以 ISO-8859-1 編碼;伺服器若以 GBK/UTF-8 解碼即產生亂碼。解決核心:統一雙端編碼或正確轉碼。
在 JSP 頁面或共用檔定義靜態方法:
<%!
public static String toChinese(String str) {
if (str == null) return null;
try {
byte[] bytes = str.getBytes("ISO-8859-1");
return new String(bytes, "GBK"); // 或 UTF-8
} catch (Exception e) { return str; }
}
%>
<%-- 使用 --%>
String name = toChinese(request.getParameter("name"));
缺點:每個取參數處皆需呼叫、易遺漏、POST/GET 需分開處理、效能稍差。
實作 javax.servlet.Filter,在 doFilter 早期設定請求編碼,並包裝 HttpServletRequest 覆寫 getParameter* 方法自動轉碼。
package filters;
import java.io.IOException;
import javax.servlet.*;
public class EncodingFilter implements Filter {
private String encoding = "UTF-8";
private boolean ignore = true;
public void init(FilterConfig config) {
String e = config.getInitParameter("encoding");
if (e != null) encoding = e;
String ig = config.getInitParameter("ignore");
if (ig != null) ignore = Boolean.parseBoolean(ig);
}
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
// POST 請求直接設定編碼
if ("POST".equalsIgnoreCase(request.getMethod())) {
if (ignore || request.getCharacterEncoding() == null) {
request.setCharacterEncoding(encoding);
}
} else {
// GET 請求需包裝 Request 覆寫 getParameter
request = new RequestWrapper(request, encoding);
}
chain.doFilter(request, res);
}
public void destroy() {}
}
// 包裝類
class RequestWrapper extends HttpServletRequestWrapper {
private String encoding;
public RequestWrapper(HttpServletRequest request, String encoding) {
super(request); this.encoding = encoding;
}
private String decode(String s) {
try { return new String(s.getBytes("ISO-8859-1"), encoding); }
catch (Exception e) { return s; }
}
@Override public String getParameter(String name) { return decode(super.getParameter(name)); }
@Override public String[] getParameterValues(String name) {
String[] vals = super.getParameterValues(name);
if (vals != null) for (int i=0;i
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>filters.EncodingFilter</filter-class>
<init-param><param-name>encoding</param-name><param-value>UTF-8</param-value></init-param>
<init-param><param-name>ignore</param-name><param-value>true</param-value></init-param>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
server.xml 的 <Connector> 加入:
<Connector port="8080" protocol="HTTP/1.1"
URIEncoding="UTF-8" useBodyEncodingForURI="true" />
即可解決 GET 參數編碼,POST 仍需 request.setCharacterEncoding("UTF-8") 或 Filter。
EncodingFilter + Tomcat URIEncoding="UTF-8"。characterEncoding=utf8(MySQL)或對應設定。encodeURIComponent() 送參數。