這幾天在折騰短信的發送問題。其實最令人苦惱的是,你明明在windows環境下一切都測試成功,能成功發送中文短信了,但偏偏你把項目部署到Linux環境的時候,卻發現中文短信發出來是避之不及的亂碼~~
其實能知道這是由於編碼的問題,但要解決它還不太容易呢。
首先,看在windows環境下正常顯示中文的原因:打開cmd窗口,輸入:chcp你會發現輸出
活動代碼頁: 936
查閱936的意義:它指明瞭當前系統使用的編碼,936 代表GBK 擴展的EUC-CN 編碼( GB 2312-80編碼,包含 6763 個漢字)到Unicode (GB13000.1-93)中定義的20902個漢字,即中國大陸使用的是簡體中文zh_CN。
這說明,在windows下是默認採用的gbk方式編碼,短信也沒有中文亂碼。
接下來再看linux環境下的中文編碼格式:輸入命令
cat /etc/sysconfig/i18n
你會發現輸出默認爲:
LANG="en_US.UTF-8"
SYSFONT="latarcyrheb-sun16"
這說明,Linux默認支持的中文編碼爲UTF-8,這與短信正常顯示中文所支持的GBK不一致。
到這一步其實有2個思考方向,第一:修改短信發送的代碼,在發送內容上修改成這樣:
smsContent = new String(smsContent.getBytes(), "gbk");
參考String的編碼解碼說明:
public byte[] getBytes(String charsetName)
使用指定的字符集將此String編碼爲byte序列,結果存在一個byte數組中
public String(byte[] bytes, String charsetName)
通過使用指定的 charsetName 解碼指定的 byte 數組,構造一個新的 String。
但經測試發現,在Linux上這樣改動時,都無法收到短信網關的回覆。。更別說中文亂碼的問題了。
第二:修改Linux的中文編碼。
執行命令:
vi /etc/sysconfig/i18n
將內容替換如下:
LANG="zh_CN.GBK" SUPPORTED="zh_CN.UTF-8:zh_CN:zh" SYSFONT="latarcyrheb-sun16"
修改保存後運行命令locale發現依然是utf-8編碼格式。。
注意,此時不要着急reboot(linux重啓系統命令,類似筆記本電腦重啓系統,需要一段時間,有造成硬件損壞風險哦),將登陸用戶先logout再login(登出後再登入),再次運行locale命令,你會發現被修改成GBK了:
LANG=zh_CN.GBK LC_CTYPE="zh_CN.GBK" LC_NUMERIC="zh_CN.GBK" LC_TIME="zh_CN.GBK" LC_COLLATE="zh_CN.GBK" LC_MONETARY="zh_CN.GBK" LC_MESSAGES="zh_CN.GBK" LC_PAPER="zh_CN.GBK" LC_NAME="zh_CN.GBK" LC_ADDRESS="zh_CN.GBK" LC_TELEPHONE="zh_CN.GBK" LC_MEASUREMENT="zh_CN.GBK" LC_IDENTIFICATION="zh_CN.GBK" LC_ALL=
但此時你有可能發現打印的日誌又亂碼了,憋着急,不是說你的系統不支持gbk顯示,而是你要修改你ssh客戶端的編碼跟系統編碼gbk一致就ok啦~~~
修改成功之後,經測試,發現通過部署到Linux環境上後,發送的短信中文顯示也不亂碼了。至於爲何手機接收短信不太支持UTF-8,具體原因沒有深究。
其實這跟我前段時間做的iReport報表問題差不多,這些問題的出現都是由於windows和linux的一些環境差異造成的。畢竟一般情況下,開發工作是在windows下完成的,然而真正部署上線的是在linux環境中。