CharacterEncodingFilter一定要放在第一個

chanjarster發表於2016-08-05

在開發java web應用的時候經常會遇到令人頭痛的字元編碼問題,期中一個就是客戶端傳送過來的請求的編碼在請求頭裡並沒有,開發人員需要在後端自己選擇合適的encoding來解析request過來的引數。

這個問題的解決辦法很簡單,就是寫一個filter來過濾所有請求,然後設定一下request的characterEncoding,比如:

public class CharacterEncodingFilter implements Filter {

  protected String encoding = "utf-8";

  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  throws IOException, ServletException {
    request.setCharacterEncoding(encoding);
    chain.doFilter(request, response);
  }

  public void init(FilterConfig filterConfig) throws ServletException {
    String initEncoding = filterConfig.getInitParameter("encoding");
    if (Strings.isNotBlank(initEncoding)) {
      this.encoding = initEncoding;
    }
  }

  public void destroy() {
    encoding = null;
  }

}

把這個filter在web.xml裡配置一下所攔截的url pattern就行了。

但是這裡有個陷阱,整個web應用裡,這個filter的攔截順序必須是第一個,否則還是會出現亂碼問題。這是因為(至少在tomcat裡):

  1. request物件的parameter並不是一開始就解析的,它是等你第一次呼叫getParameter*等凡和獲得請求引數有關的方法的時候才解析的

  2. paramter一旦被解析過一次,那就不會再次被解析

所以如果在CharacterEncodingFilter之前有另外一個filter,而這個filter呼叫了getParameter*方法,那麼就有可能使用錯誤的encoding來解析,從而造成亂碼問題。

相關文章