項目中,有些業務數據存放在blob類型的字段中,常遇到的一個問題就是中文亂碼。本人蔘與的一個項目,在windows環境下,中文正常顯示,有一天切換到了Linux服務器上,同樣的代碼,竟然出現了中文亂碼。亂碼並不可怕,解決方式無非是統一編碼。於是乎,先查看了一下用的Oracle數據庫的字符集
select * from nls_database_parameters where parameter ='NLS_CHARACTERSET';
查詢結果是ZHS16GBK,也就是對應GBK編碼。又在網上查了下資料,說windows默認GBK編碼,Linux默認UTF-8,怪不得在window環境下沒事,Linux環境下就亂碼了。問題原因搞清楚了,下一步着手解決。
是改數據庫編碼呢還是改服務器編碼呢?分析了下,Oracle改默認編碼很麻煩而且還可能有隱患,並且我的項目還跟別的項目共用一個數據庫,安全起見還是改服務器編碼吧。
Linux系統版本:CentOS release 6.9 (Final)
先輸入命令:locale
果然都是UTF-8,嘗試了下面方法:
/root/.bash_profile文件的末尾添加以下兩行命令:
export LC_ALL="zh_CN.GBK"
export LANG="zh_CN.GBK"
重新啓動服務器後,重新輸入命令:locale
很高興的發現都變成了GBK,以爲搞定了,結果做了下測試還是亂碼,百思不得其解。又試了些別的法,也不行,無奈先在項目啓動後追加些打印環境編碼的代碼看看吧:
System.out.println("Default Charset=" + Charset.defaultCharset());
System.out.println("file.encoding=" + System.getProperty("file.encoding"));
System.out.println("Default Charset=" + Charset.defaultCharset());
System.out.println("Default Charset in Use=" + getDefaultCharSet());
private static String getDefaultCharSet() {
OutputStreamWriter writer = new OutputStreamWriter(new ByteArrayOutputStream());
String enc = writer.getEncoding();
return enc;
}
果然,打印出來的結果還是UTF-8
又找了個方法試了試:
修改 /etc/sysconfig/i18n 文件
修改爲:
LANG="zh_CN.GBK"
SUPPORTED="zh_CN.UTF-8:zh_CN:zh"
SYSFONT="latarcyrheb-sun16"
修改完後,執行:source i18n,再測試,成功解決。本以爲這樣的問題都能這麼解決的,後來在公司的開發服務器上又試了一把,結果不好使。
公司服務器版本:Red Hat Enterprise Linux Server release 6.4 (Santiago)
最後又用了下面的方法:
在/etc/profile文件的最後一行添加如下內容:
export LANG="zh_CN.GBK"
export LC_ALL="zh_CN.GBK"
問題解決了。
總結,不同的情況多試試,不行就打印出運行環境的編碼方式看看。