在開發中,總會碰到各種中文亂碼問題,下面稍作總結。
1、資料庫的亂碼
出現亂碼問題,我們第一反應應該是:是否資料庫字元編碼設定有問題。以mysql為例,裝好mysql後進入安裝目錄,開啟my.ini配置檔案檢視mysql設定的編碼。在my.ini中有兩處設定字元編碼的地方,分別是[mysql]下的default-character-set及[mysqld]下的default-character-set。熟悉linux的朋友都知道以d結尾的表示服務端,如你想那樣,[mysql]設定的字元編碼是客戶端的,[mysqld]設定的字元編碼是mysql伺服器端的編碼。我們的資料就是儲存在mysql伺服器端的,為了能存下任何字元編碼的資料,我們一般設定[mysqld]下的default-character-set=utf8(注意,不是utf-8)。代表客戶端的[mysql]下的default-character-set應該怎麼設定呢,一般朋友可能也設定成utf8,這可能會出問題的。如果這樣設定的話,當我們”執行cmd”開啟DOS視窗,通過”mysql -uroot -p123″命令進入mysql的客戶端後,我們是不能插入中文的。道理很簡單,這是因為我們的作業系統的字元編碼是GBK(或GBK相容),我們在DOS視窗輸入的中文(如:insert into test values(`中文`))自然也是GBK的,而我們[mysql]設定的卻是utf8,因為不相容所以會出錯。當然,如果我們使用相關mysql的GUI客戶端工具,進行相關設定,即使[mysql]設定成utf8也沒問題。但如果通過DOS視窗登陸mysql客戶端時,一般要設定[mysql]下的default-character-set=GBK。
總結:[mysql]下default-character-set=GBK,[mysqld]下default-character-set=utf8
2、使用GET請求的亂碼
如果一個請求是GET方式時,比如<a href=”url”>標籤指定的請求如form表單以GET方式提交,我們可以在瀏覽器位址列上看到類似http://localhost/proj/a.do?title=%C4%E3%BA%C3 這樣的URL。像這樣2個(%加上2位16進位制數)表示一箇中文,這是用ISO8859-1(即lantin1)進行的編碼。對於這樣用GET請求的URL中的中文字元,我們是不能通過設定request.setCharacterEncoding(“UTF-8”)來解決的。
解決方法有兩種:
第一種方法是用 title = new String(title.getBytes(“ISO8859-1”), “UTF-8”); 來對每個有中文的請求引數進行解碼再編碼,這種方法比較繁瑣;
第二種方法是修改tomcat的server.xml配置檔案,把<Connector port=”8080″ …>修改成 <Connector port=”8080″ … URLEncoding=”UTF-8″>,即在<Connector>元素中指定其URLEncoding=”UTF-8″,其預設值為lantin1。這屬性指定了URL的編碼,設定成UTF-8後,位址列上就不會再出現 a.do?title=%C4%E3%BA%C3 之類的內容了,而是 a.do?title=中文 。
這種方法的缺點是,其它專案或該專案其它地方可能會因為修改而引入了新的中文編碼問題,比如使用這種方法之後,有些地方使用了第一種方法處理好了的中文將會再次變成亂碼。這種方法不常用,可能牽一髮而動全身。
3、使用POST請求的亂碼
對於form表單以POST提交的請求,可以用request.setCharacterEncoding(“UTF-8”)來解決。至於為什麼這種方法對POST請求有效而對GET請求無效,請參考HTTP協議中GET與POST請求的差別,簡單來講就是GET請求的內容放在請求頭裡,POST請求是放在請求體來。一般來講我們可以通過給專案增加一個字符集過濾器來一次性解決POST請求的中文亂碼。過濾器裡的內容非常簡單,就是呼叫request.setCharacterEncoding(encoding),encoding是我們要設定的字符集。過濾器可以自己編寫,也可以使用spring提供的org.springframework.web.filter.CharacterEncodingFilter。
綜上所述我們在中文亂碼這個問題上,一般的做法如下:
a、編碼集用UTF-8而不是GBK
b、給我們的應用加上一個字符集過濾器
c、所有的Form表單都以POST進行提交
d、用連結<a href=”a.do?name=中文”>進行的提交,最好用new String(title.getBytes(“ISO8859-1”), “UTF-8”)來解決而不是修改tomcat的配置檔案