楊麗慧
(河北民族師范學院 信息中心,河北 承德 067000)
如何解決Tomcat的亂碼
楊麗慧
(河北民族師范學院 信息中心,河北 承德 067000)
針對在JSP/Servlet程序設計中,服務器用Tomcat在頁面上經(jīng)常會看到亂碼。就這個問題提出幾種解決的方法。
tomcat;JSP/Servlet;GET;POST;Filter
開發(fā)項目時,用JSP/Servlet編程,服務器用tomcat,經(jīng)常會看到亂碼。所以就亂碼的問題同大家探討一下。
在JSP/Servlet中主要在以下幾個地方可以設置編碼,<%@page pageEncoding=“UTF-8”%>,建議在每個頁面上都加上pageEncoding設定,讓應用服務器能正確把JSP文件按照設定的編碼轉(zhuǎn)換為Java文件,只要這個pageEncoding設置正確就可以避免靜態(tài)內(nèi)容的亂碼。有的時候沒有設置也沒有亂碼,那是因為應用服務器還可以讀取<%@page content-Type=“text/html;charset=UTF-8”%>中的charset作為備選方案,雖然這是JSP規(guī)范中要求的,但是難保有的容器沒有實現(xiàn)或?qū)崿F(xiàn)有BUG,所以有時候在某個應用服務器下 (如Tomcat)不設置pageEncoding也可以,但是同樣的頁面拿到別的應用服務器下就有可能出現(xiàn)亂碼。
新下載的Tomcat沒有經(jīng)過任何特殊的設置,無論是GET和POST都出現(xiàn)亂碼。首先設置HTTP Connector(server.xml中監(jiān)聽8080端口的那個Connector),加上URIEncoding=“UTF-8”,消除了GET亂碼,再在 JSP頁面中第一句加入<%request. setCharacterEncoding(“UTF-8”)%>,消除了POST亂碼。通過上面兩個設置我們發(fā)現(xiàn),URIEncoding控制的是GET字符集編碼,Request的CharacterEncoding控制的是POST字符集編碼。
上面提到的<%@page contentType=“text/html;charset=UTF-8”%>,除了聲明返回給客戶端的流是text/html外,同時設置了Response的CharacterEncoding,相當于執(zhí)行了Response.setCharacterEncoding (“UTF-8”)這段代碼。它保證了服務器端生成的動態(tài)內(nèi)容到達客戶端也不會亂碼。
但有一種情況下也不會出現(xiàn)亂碼,就是如下例這種情況,前提是沒有設置Request的CharacterEncoding:
1 protected void doPost(HttpServletRequest request ,HttpServletResponse response) throws ServletException,IOException{
2 response.getWriter().write(request.getParameter(“xxxxx”));
3}
這種情況下提交過來的表單數(shù)據(jù)其實是ISO-8859-1的編碼,而返回給客戶端又沒有<%@page contentType=“text/html;charset=UTF-8”%>的設置,所以還是ISO-8859-1的編碼,但是為什么沒有亂碼呢?其實已經(jīng)亂碼了,如果在第2行下斷點的話,會發(fā)現(xiàn)request.getParameter(“xxxxx”)的返回值就是亂碼??梢杂靡痪銳ava代碼來解釋為什么客戶端顯示結果沒有亂碼,如下:
System.out.println(new String(“你好,世界”.get-Bytes(“ISO-8859-1”),“ISO-8859-1”);
很奇怪這句代碼,明明是中文,應該用GB2312或GBK之類的字符集編碼來getBytes,卻用了ISO-8859-1,事實證明,這種互逆操作對字符串本身沒有任何影響,只要getBytes和new String的時候字符集編碼是一致的就不會引起亂碼。
上面這句代碼正好說明了數(shù)據(jù)從客戶端POST到服務器端時是ISO-8859-1編碼,然后從服務器端寫回到客戶端還是ISO-8859-1編碼,所以就沒有造成亂碼,如果這里不是直接寫回到客戶端,而是forward到另一個JSP頁面,而這個頁面恰好使用了<%@page contentType=“text/html;charset=UTF-8”%>來設置Response的CharacterEncoding,那么在頁面中輸出xxxxx還會產(chǎn)生亂碼,同樣用一句Java代碼來解釋,如下:
System.out.println(new String(“你好,世界”.get-Bytes(“ISO-8859-1”),“UTF-8”));
所以,最后結論是如果想POST到服務器端不亂碼就要設置Request的CharacterEncoding,寫回到客戶端不亂碼就要設置 Response的CharacterEncoding,若是JSP頁面要設置<%@page contentType=“text/html;charset=UTF-8”%>。
GET請求時,需要對 queryString使用 encodeURIComponent()編碼之后再提交到服務器。這是XMLHttpRequest規(guī)范所要求的。
POST請求時,不需要使用encodeURIComponent()。
通過對應用程序下斷點發(fā)現(xiàn),GET請求和POST請求的數(shù)據(jù)發(fā)送到服務器端都是正常的沒有亂碼,但是服務器端生成的動態(tài)內(nèi)容寫回客戶端卻是亂碼,說明Response的CharacterEncoding設置錯誤,反過來我們再想一下,根本就沒有設置過Response的CharacterEncoding,為什么呢?因為是以AJAX的方式提交表單,返回后不像JSP頁面那樣有<%@page contentType=“text/html;charset=UTF-8”%>來設置Response的CharacterEncoding,所以就會出錯。
綜合上述,解決的辦法就是各大網(wǎng)站提出的通用解決方案Filter,如果應用沒有用到AJAX,只設置Request的CharacterEncoding即可,否則Response的CharacterEncoding也要設置。
TP3
A
2095-3763(2012)02-0062-02
2012-01-05
楊麗慧(1972-),女,河北張家口人,河北民族師范學院信息中心副教授,碩士。