1. 程式人生 > >程式設計過程中字元編碼亂碼問題彙總

程式設計過程中字元編碼亂碼問題彙總

一、避免 亂碼 的一些注意點:
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 = " Get SelectListAction.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。修改環境變數的方法不到萬不得已不推薦使用。