亂碼問題處理彙總

亂碼對於使用非英語文字程序員基本上是一直纏繞在身邊的麻煩事,這個誰也避免不了。下面是我解決亂碼時候的一點小經驗。歡迎指正
 
一、避免亂碼的一些注意點:
1.儘量使用統一的編碼,如果你是重頭開發一個系統,特別是Java開發的,推薦從頁面到數據庫再到配置文件都使用UTF-8進行編碼,安全第一。
2.SetCharacterEncodingFilter的使用,這個東西不是萬能的,但是沒有它就會很麻煩,如果是基於Servlet開發的東西,能用的就給它用上,省心。不過有一個注意的地方,這個Filter只是對POST請求有效,GET一律忽略,不信你可以debug一下,看看它怎麼做的,至於爲什麼不過濾get請求,好象是它對GET請求是無能爲力的。
3.就如上面所說,GET請求有問題,儘量使用POST請求,這個也是Web開發的一個基本要領:
Web Health Warning:Put All Destructive Actions Behind a POST method(from Agile Web Development with Rails)
有點扯遠了,不過少用GET,是會有回報滴。
4.JavaScript和Ajax亂碼的避免,注意JavaScript默認是ISO8859的編碼,避免JS/AJAX亂碼和GET一樣,不要在URL裏面使用中文,實在避免不了,就只能在生成鏈接的時候轉碼,絕對不能想當然的認爲SetCharacterEncodingFilter會幫你做什麼事情。
5.儘早統一開發環境,早點模擬真實環境測試,這個好像也有跑題的嫌疑,但凡軟件開發都是這麼幹的,但仍然值得注意。我這出現過一次狀況,程序是在Win下編譯的,拿去Linux上測試沒問題,等實際部署的時候代碼是在Linux下編譯,結果亂碼,秋後算帳總覺得有點晚。

二、亂碼發生的情況和應對措施
1.開發環境亂碼
      由於Java默認使用UTF-8編碼,而且網上很多人都建議Struts開發的時候應儘量選用UTF-8做爲默認編碼,而非GBK。IDE使 用Eclipse,在第一次使用Eclipse的時候應將default text editor改爲UTF-8編碼,免得日後後悔再改就慘了,我本次開發的時候就忽視了這一點,剛開始沒注意,結果到快交工時亂碼問題無法解決,導致將所有 的文件全部修改一遍,嗚……
      自打使用Ubuntu,我就開心的笑阿,再也不用爲搞這些亂碼問題而煩惱^^(Ubuntu公益廣告)
2.POST請求的過濾
      這個是最基本的了,每個Servlet系統基本都會用到這個東西。不過只對POST請求有效,這個挺關鍵的。
      使用SetCharacterEncodingFilter,這個很基礎的一套過濾器,將所有來自頁面的POST請求全部過濾爲UTF-8編碼。
3. JSP ,HTML頁面亂碼
     將JSP頁面全部改爲charset=UTF-8,這樣可以保證與後臺交互的時候都是UTF-8編碼,一般應用做了以上工作就基本可以應付了。
4.資源文件中漢字轉化UTF-8字符問題
      國際化問題,在使用資源文件的時候,由於中文在properties文件中無法被程序所識別,需要將其進行轉碼,我在資源文件下面製作了一個很簡單的 bat文件,每次修改資源文件的時候都是在一個臨時文件中修改,然後執行這個bat文件,將其轉化並保存爲所需要的資源文件,這個動作挺煩的,也有項目組 成員使用一些插件,但是那些東西都是直接寫UTF-8碼的,有時候反倒不方便,不過以後任務量巨大的時候可能會考慮使用。Bat文件內容:   set path=%path%;%JAVA_HOME%/bin/,native2ascii -encoding UTF-8 ApplicationResources_bk.txt > ApplicationResources_zh.properties

     PS:上面的方法好老了,實際操作起來相當麻煩,現在基本都是使用Eclipse插件,Eclipse3.1時使用PropertyEditor,但是這 個項目看上去好像停擺了,到Eclipse3.2時改用了ResourseBundle,相當的強勁的一個插件,推薦使用。
5. GET請求亂碼
      如果在本項目中採用了get方式提交請求並附加參數,結果導致編碼亂碼,原因是Tomcat默認請求編碼是ISO8859,需要在Tomcat的配置文件 server.xml添加一個參數,URIEncoding=”UTF-8”,這樣請求中附件的參數就會以UTF-8來進行編碼。
6.Ajax請求亂碼
    使用Ajax,JS也是默認使用ISO8859編碼,所以在進行請求時遇到中文參數需要進行編碼,如:var url = "GetSelectListAction.do?queryData=subTrade" + "&queryId=" + encodeURI(obj.value) + "&r=" + Math.random();  
    這裏有兩個地方需要注意:第一個地方是encodeURI(),方法,可以將參數進行轉碼,默認是轉化爲UTF-8,如果需要轉爲其他碼制,需要在方法中添加第二個參數。
     第二個地方是Math.random(),由於Ajax有緩存機制,在接受請求的時候第一時間先判斷該請求的地址是否被訪問過,如果被訪問過則 直接使用緩存中的內容返回,這個東西很討厭,客戶在訪問過一次出錯後以後每次出現的都是這個錯誤,所以在請求中給其增加一個時間戳,只要可以隨機生成一個 不同的字串就可以,保證Ajax每次都去訪問服務器。
7. GET方法的另一個亂碼問題
      在項目即將交工的時候突然又出現亂碼問題,發現對於超長的漢字做爲參數傳遞仍然會出現亂碼問題,解決方法是採用java.net.URLEncoder的 Encode方法強制轉碼,缺點是會使JSP頁面代碼相當的長,但是目前還沒有其他好的解決辦法,我想最好的辦法就是不用中文做爲參數傳遞 :P,寫法如:<a href="TestAction.do?name=<%= java.net.URLEncoder.encode("你好","UTF-8")%>

8.亂碼仍然是偶們的心病,一直牽動着大家的心,最近一位朋友說連接MSSQL數據庫有亂碼,使用了很多辦法,都沒解決,後來重新下了個新的驅動搞定……
數據庫亂碼其實也很討厭的,一般來說驅動問題比較常見,所以一旦碰到比較難纏的亂碼可以先考慮下換換驅動。也有如MySQL這種,直接連接的時候就需要顯示進行編碼轉化的,這個就要不同情況區別對待了。

//2007年11月30日添加
9.WebService亂碼,由於對WebService不怎麼熟悉,使用的是Weblogic提供的WebService支持,亂碼再次出現搞得手忙腳亂,而且無從下手,在自己系統上跑都沒有問題,結果跑到服務器上就全亂套,又無法調試,愁人。
    反覆嘗試的過程就不說了,絕對比普通的Web開發麻煩的多。最終解決方法:
    A.爲WebService服務也加上一個filter,WebService也是走HTTP協議的,這個東西同樣有用,先得加上。
    B.修改服務器上的環境變量,LANG=zh_CN.UTF-8,改成這個是爲什麼我仍然說的不是很清楚,不過當時開發人員就是在Win下開發的,我在自己的Ubuntu上測試沒問題,拿到Redhat服務器上就不行,因爲服務器上默認的是LANG=en_US.UTF-8,這個明顯是不支持漢字的。
    經過這兩個步驟WebService亂碼總算得到抑制,它主要的麻煩在於所有與協議有關的東西都被Weblogic包辦,裏面做什麼事情我們不好控制,所以只能採取這種比較笨的辦法,雖然解燃煤之急但無法尋根溯源的搞定它,說不定哪天又會出來搞鬼。果然又一次出現亂碼問題,經過比較環境變量發現服務器上的LC_CTYPE被修改了,所以強制改成LC_CTYPE=zh_CN。修改環境變量的方法不到萬不得已不推薦使用。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章