在開發 Web 項目時,解決中文亂碼問題是不可避免的。在前面所學的知識中,解決亂碼的通常做法是在 Servlet
程序中設置編碼方式,但是,當多個 Servlet
程序都需要設置編碼方式時,就會書寫大量重復的代碼。
為了解決這一問題,我們可以在 Filter
中對獲取到的請求和響應消息進行編碼處理,這樣就可以實現全站編碼方式的統一。本節將分步驟演示如何使用 Filter
實現全站編碼的統一。
創建過濾器
創建一個名稱為 CharacterFilter 的 Filter 類,該類用于攔截用戶的請求訪問,并實現全站編碼的統一,其具體實現代碼如下所示:
public class CharacterFilter implements Filter {
public void init(FilterConfig fConfig) throws ServletException {
}
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
// 攔截所有的請求,解決全站中文亂碼,指定request和response的編碼
request.setCharacterEncoding("utf-8"); // 只對消息體有效
response.setContentType("text/html;charset=utf-8");
chain.doFilter(request, response);
}
public void destroy() {
}
}
修改配置文件web.xml
在 CharacterFilter 中,針對請求的方式不同,采用了不同的亂碼解決方式。其中,由于 POST 方式的請求參數存放在消息體中,所以通過 setCharacterEncoding() 方法進行設置,而 GET 方式的請求參數存放在消息頭中,通過 HttpServletRequestWrapper 類對 HttpServletRequest 類進行包裝,并通過重寫 getParameter() 的方式設置 GET 方式提交參數的編碼。
需要注意的是,由于要攔截用戶訪問資源的所有請求,因此需要將 CharacterFilter 映射信息中 <filter-mapping> 元素攔截的路徑設置為“/*”,如下所示:
<filter>
<filter-name>CharacterFilter</filter-name>
<filter-class>com.example.filter.CharacterFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>