Spring 字符集過濾器CharacterEncodingFilter

1.CharacterEncodingFilter源碼解析

public class CharacterEncodingFilter extends OncePerRequestFilter {
    private String encoding;
    private boolean forceRequestEncoding;
    private boolean forceResponseEncoding;

    public CharacterEncodingFilter() {
        this.forceRequestEncoding = false;
        this.forceResponseEncoding = false;
    }

    public CharacterEncodingFilter(String encoding) {
        this(encoding, false);
    }

    public CharacterEncodingFilter(String encoding, boolean forceEncoding) {
        this(encoding, forceEncoding, forceEncoding);
    }

    public CharacterEncodingFilter(String encoding, boolean forceRequestEncoding, boolean forceResponseEncoding) {
        this.forceRequestEncoding = false;
        this.forceResponseEncoding = false;
        Assert.hasLength(encoding, "Encoding must not be empty");
        this.encoding = encoding;
        this.forceRequestEncoding = forceRequestEncoding;
        this.forceResponseEncoding = forceResponseEncoding;
    }

    //...

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String encoding = this.getEncoding();
        if (encoding != null) {
            if (this.isForceRequestEncoding() || request.getCharacterEncoding() == null) {
                request.setCharacterEncoding(encoding);
            }

            if (this.isForceResponseEncoding()) {
                response.setCharacterEncoding(encoding);
            }
        }

        filterChain.doFilter(request, response);
    }
}

通過源碼,我們知道,CharacterEncodingFilter構造函數最多可以指定三個參數: encoding, forceRequestEncoding, forceResponseEncoding``。

1.forceRequestEncoding強制指定:request.setCharacterEncoding("XXXX");

  1. forceResponseEncoding強制指定: response.setCharacterEncoding(“XXXX”);
    強制ServletResponse的編碼格式和ServletRequest的編碼格式一樣。
@RequestMapping(value="XXXXX")  
public void XXXXX(User user,HttpServletRequest req,HttpServletResponse resp) throws UnsupportedEncodingException  
{  
       resp.setCharacterEncoding("UTF-8");  
       req.setCharacterEncoding("UTF-8");  
      //......  
}  

因此,在請求處理的過程中我們可以不用考慮編碼方面的問題,上面兩句代碼可以省略,編碼統一交給Spring過濾器去處理,我們可以專心處理我們的業務邏輯代碼。


2.CharacterEncodingFilter對GET方法參數無效

不妨看看CharacterEncodingFilter內的實現 doFilterInternal該方法調用
request.setCharacterEncoding(this.encoding);

而該方法的說明
Overrides the name of the character encoding used in the body of this request. This method must be called prior to reading request parameters or reading input using getReader().

只對body起作用


3.CharacterEncodingFilter 要是第一個執行的filter

整個web應用裏,這個filter的順序必須是第一個,否則還是會出現亂碼問題。這是因爲:
request對象的parameter並不是一開始就解析的,它是等你第一次調用getParameter獲得請求參數有關的方法的時候才解析的。paramter一旦被解析過一次,那就不會再次被解析。

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


4.response中setCharacterEncoding和setContentType的區別

setCharacterEncoding只是設置字符的編碼方式
setContentType除了可以設置字符的編碼方式還能設置文檔內容的類型

response.setContentType("text/html;charset=utf-8");
等於
response.setHeader("content-type", "text/html;charset=utf-8");
等於
response.setHeader("content-type", "text/html");
response.setCharacterEncoding("utf-8");
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章