開始用JAVA做J2EE項目的時候, 很多人會遇到亂碼問題,這個比較好解決,網(wǎng)上有很多成熟的解決方案,原理也廣為大家所知。 我下面只簡述一下這種情況下亂碼的原因及解決方案:無論是Struts用的action還是、jsp頁面、或者其它,最終會被編譯成servlet程序由用戶來調(diào)用。這些servlet是以UNICODE編碼的。其實servlet用什么編碼并不重要,重要的是servlet的輸入和輸出以同樣的方案編碼就不會有亂碼。 常見的亂碼有兩種:一個是表單提交出現(xiàn)亂碼;一個是以地址欄傳參數(shù)出現(xiàn)亂碼。 針對第一種形式的亂碼,可以在每個jsp頁面加上<%@ page pageEncoding="GB18030"%>注:jsp2.0適用; 或者加上<%@ page contentType="text/html; charset=GB18030"%>,“GB2312”、“GBK”、“UTF-8”也可以,反正整個系統(tǒng)中統(tǒng)一就可以。還有一種方式是使用request.setCharsetEncoding("GB18030"),可以使用Filter統(tǒng)一處理。 針對地址欄參數(shù)出現(xiàn)亂碼的情況,解決方案如下(tomcat適用,其它的沒有弄過): 在tomcat的配置文件:server.xml中,找到connector元素,在后面加上一個屬性ERIEncoding="GB18030",GB18030是我用的編碼方案,在讀者的項目中,可以設(shè)定成系統(tǒng)中統(tǒng)一使用的編碼方案。注意connector元素有兩個,一個是針對http,一個是針對https,可以都加上。
下面討論一下Ajax方式下的亂碼問題:首先,如果整個項目使用UTF-8編碼,并對request(調(diào)用xmlhttp對象的setrequestheader("contentType","text/html;charset=uft-8")方法)進(jìn)行了正確的編碼,就不會有亂碼;如果整個項目選用了GB18030方案編碼,那么一般情況下會出現(xiàn)亂碼。產(chǎn)生的原因就是:xmlhttp使用了UTF-8方案對傳遞的參數(shù)進(jìn)行編碼(這也是整個項目使用UTF-8編碼不出現(xiàn)亂碼的原因)。我們可以做一個試驗對此進(jìn)行驗證: String str ="博客"; String newstr = new String(str.getBytes("UTF-8"),"GB18030"); 如果你的系統(tǒng)使用的WINDOW,項目使用的是GB18030(或者GBK或者GB2312),輸出newstr就會是亂碼,這個亂碼應(yīng)該與你使用ajax提交中文“博客”所得到的亂碼是一致的。 還有個問題, String newstr2=new String(newstr.getBytes("GB18030"),"UTF-8");這樣再得到一個新的字符串,這個字符串與初始的字符串str并不相同,最后一個字會是亂碼,這個我不知道是什么原因,那們知道原因請告訴我一下。 這樣,知道了原理就可以找方法來避免亂碼了。經(jīng)過試驗我找到兩種方法來解決Ajax的亂碼問題(其實原理是一樣的): 前提是使用setrequestheader方法進(jìn)行了正確的編碼(POST方式提交數(shù)據(jù)時,要使用xxx-application-url方案編碼,不知寫對了沒有。呵呵。)。 一、提交中文后,服務(wù)器端使用 先使用UTF-8編碼提取參數(shù): request.setCharsetEncoding("UTF-8"); String str = request.getParameter("param"); 這樣就可以得到正確的參數(shù)。 二、可以使用encodeURI進(jìn)行兩次編碼,然后在服務(wù)器端使用以下方式(這個是我以前的解決方案,顯得很土,主要是當(dāng)時對亂碼原理沒有弄清): String str = request.getParameter("param"); 然后使用下面的方式進(jìn)行解碼: java.net.URIDecode.decode(str,"UTF-8") 這樣同樣可以得到正確的參數(shù)。
/************************/ 作者:王力猛 (wallimn) 電郵:wallimn@sohu.com 博客:http://wallimn. http://blog.csdn.net/wallimn 時間:2006-11-15 /************************/
今天終于解決了AJAX的中文亂碼問題,寫篇文章來幫助一下有同樣問題的朋友們。我的開發(fā)環(huán)境:XP, eclipse,使用GB18030編碼。 當(dāng)遇到這個問題時,到網(wǎng)上去查了好多文章,提到幾種解決方案,如:全站UTF-8編碼;請求頭編碼為中文;使用javascript中的escape函數(shù)。 使用GET方式提交數(shù)據(jù)的時候,中文問題很好解決,setrequestheader("Content-Type","text/html; encoding=gb18030")就可以了。但這個方法在POST方式中卻不起作用。大家都知道GET方式提交數(shù)據(jù)有長度限制,有時我們必須使用POST方式來提交數(shù)據(jù)。 但對于POST方式,使用上述的幾種方法經(jīng)過多次測試,問題依舊。我郁悶了好幾天。 今天把問題解決了,很簡單,是使用escape(或encodeURI,兩個函數(shù)javascript的函數(shù),功能基本相同,可以查一下相關(guān)的幫助),但要使用兩次,這是解決問題的關(guān)鍵。 我的例子涉及兩個頁面,一個是初始頁面,一個是AJAX請求處理頁面。 初始頁面內(nèi)容如下(hello.jsp): ///////////////////////////////////////////////////////////////////////////////////// <%@ page language="java" import="java.util.*" pageEncoding="GB18030"%> <%String path = request.getContextPath();%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>AJAX提交頁面</title> <meta http-equiv="Content-Type" content="text/html; charset=GB18030"> <script type="text/javascript"> function justdo(){ var post="name=王力猛< } %> </body> </html> ///////////////////////////////////////////////////////////////////////////////////// 分析:當(dāng)調(diào)用request.getParameter()函數(shù)時,會自動進(jìn)行一次URI的解碼過程,調(diào)用時內(nèi)置的解碼過程會導(dǎo)致亂碼出現(xiàn)。而URI編碼兩次后,request.getParameter()函數(shù)得到的是原信息URI編碼一次的內(nèi)容。再用可控的解碼函數(shù)java.net.URLDecoder.decode()就可解出原始的正確的信息。 以上分析純屬個人看法,不知是否正確。
|