java处理中文字符_Java中文字符处理的四大迷题
雖然計算機(jī)對英文字符的支持非常不錯,我們也恨不得寫的程序只會處理英文的數(shù)據(jù),但是昨為中國人,無可避免地要處理一些中文字符。當(dāng)很簡單的一件事情,遇到了中文,一切就不同了!本文就會講述實際生產(chǎn)環(huán)境中遇到的四個中文迷題,歡迎大家參與補(bǔ)充!
1、“我”講的其它機(jī)器聽不懂?
當(dāng)把一串中文字符,通過HTTP、TCP方式傳遞到另外一個系統(tǒng)時,會經(jīng)常驚奇地發(fā)現(xiàn),在發(fā)送前還是好好的,但是收到后卻全壞了!怎么辦?下面提供幾種情況,對癥下藥:
(1)發(fā)送時使用的GET請求
要特別注意傳遞參數(shù)時,不要直接使用中文(如?key=熱情),這基本就宣告了這個代碼在某個瀏覽器、某個機(jī)器上,對方收到的東西就是亂碼了。必須要對傳遞的參數(shù)進(jìn)行Url Encode,接受方再進(jìn)行Url Decode,取出來的數(shù)據(jù)基本就是OK的了。注:某些Java框架(如Spring)的RestTemplate會自動對GET方式的調(diào)用參與進(jìn)行Encode、Decode,你就可以不用再人工去做了。
(2)使用了byte傳遞數(shù)據(jù)
在使用MQ、原生Socket等場景下,有時要用byte傳遞數(shù)據(jù)。這時一定要對String的getBytes方法傳遞編碼參數(shù),一般用"UTF-8",且接收方則用new String(bytes, "UTF-8")來構(gòu)造字符串,不然也有亂碼風(fēng)險!建議對需要用byte傳遞數(shù)據(jù)的場景,盡量轉(zhuǎn)為Base64編碼的方式進(jìn)行傳遞,更方便去調(diào)試程序。
(3)設(shè)置運行環(huán)境編碼
如果你的系統(tǒng)默認(rèn)編碼未設(shè)置對,那么默認(rèn)的Java代碼運行環(huán)境也不對,所以一要在程序運行時對Java代碼運行環(huán)境進(jìn)行設(shè)置。以Linux Shell為例,在啟動應(yīng)用的shell里,增加
export LANG=en_US.UTF-8
這可以保證應(yīng)用在調(diào)用系統(tǒng)命令行時,運行環(huán)境是以UTF-8編碼的。另外如果是Tomcat,那么的腳本處也加上參數(shù)項:
-Dsun.jnu.encoding=UTF-8 -Dfile.encoding=UTF-8 -Duser.language=en -Duser.country=US
再修改tomcat默認(rèn)編碼(ISO-8859-1)方法,修改tomcat根目錄的conf下的server.xml,Connector元素添加URIEncoding="UTF-8"屬性:
這可以保證應(yīng)用的Java代碼的默認(rèn)運行是在UTF-8編碼基礎(chǔ)上的,如果需要通信的系統(tǒng)全設(shè)置為UTF-8,可以避免諸多編碼轉(zhuǎn)換!
2、瀏覽器不認(rèn)識“我”?
一般來說,瀏覽與應(yīng)用的交互就是GET、POST請求了,當(dāng)然還有PUT、DELETE請求,不過觸類旁通,不需要講太多。
POST請求的中文數(shù)據(jù),經(jīng)常是可以正常在前后臺傳遞的,但是GET請求就沒那么幸運了,一定要記得進(jìn)行URL Encode與Decode,養(yǎng)成好的編碼習(xí)慣,減少后續(xù)調(diào)試代碼的難度與時間。
3、猜一猜“我”說的是什么?
在讀寫含中文文本的文件時,有時候也會讀出亂碼來,原因是因為程序的運行編碼永遠(yuǎn)只有默認(rèn)的一種的,那么如果不帶編碼參數(shù)地去讀取文件,由于文件編碼可能與程序編碼不同,最后讀出來的就是亂碼了。這個時候,就需要寫程序去“猜”文件的編碼了。
現(xiàn)在有許多開源的識別編碼的類庫可以直接使用,但是也并不全是ok的,常見的編碼能識別就好,像這些:UTF-8、GB2312、GBK、GB18030、UTF-16、US-ASCII、Big5、ISO-8859-1,遇到的概率非常大。我這里推薦幾個:EncodingDetecotr、jChardet。
在讀取到byte后,通過編碼識別再存為相應(yīng)的String,就可以得到正常的中文了。
4、聽說UTF-8還有BOM?
BOM,在UCS編碼中有一個叫做"ZERO WIDTH NO-BREAK SPACE"的字符,它的編碼是FEFF,這就是所謂的BOM頭了,它的UTF-8編碼是EF BB BF。在Windows系統(tǒng)上,默認(rèn)用記事本存儲為UTF-8格式,是有BOM的,但是Linux下卻是默認(rèn)無BOM的。缺了BOM的文件,經(jīng)常在Windows下就識別出現(xiàn)錯位、亂碼等問題。解決之道就是在讀取文件、byte的前幾個字節(jié),如果無BOM就給它加上BOM。
1 /**
2 * 判斷文件是否有BOM3 *4 *@return
5 */
6 public static booleanhasBom(File file) {7 FileInputStream input = null;8 try{9 input = newFileInputStream(file);10 byte[] buf = new byte[1024];11 if ((input.read(buf, 0, 1024)) != -1) {12 if (buf[0] == (byte) 0xEF && buf[1] == (byte) 0xBB && buf[2] == (byte) 0xBF) {13 return true;14 }15 }16 return false;17 } catch(IOException e) {18 _logger.error(e);19 return true;20 } finally{21 if (input != null) {22 try{23 input.close();24 } catch(IOException e) {25 _logger.error("資源釋放失敗!", e);26 }27 }28 }29 }
如果無BOM,則在傳給Windows的地方或需要導(dǎo)出的地方這前先加上:new byte[] {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF} 這些字節(jié)。
以上這些點如果注意了,常見的中文編碼問題就解決了,如果還有新的坑,博主會在此更新哈。
總結(jié)
以上是生活随笔為你收集整理的java处理中文字符_Java中文字符处理的四大迷题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 送母亲花有哪几种种类
- 下一篇: 养生堂的维生素E含量纯吗?其含量是多少?