今天寫的一個服務(wù)程序,有人報(bào)告獲得的數(shù)據(jù)中文亂碼锡凝,而我是用 apache 通過 httpComponents 去取得數(shù)據(jù)的,于是開啟日志的 debug 級別张肾。
在日志里果然發(fā)現(xiàn)中文不見了锚扎,有亂碼出現(xiàn):
2014-07-02 16:35:01.348 DEBUG [Wire.java:86] http-outgoing-8 << "<?xml version="1.0" encoding="UTF-8"?>... subject="[0xe6][0x88][0x91][0xe6][0x98][0xaf][0xe4][0xb8][0xad][0xe6][0x96][0x87][0xe4][0xb8][0xbb][0xe9][0xa2][0x98]" ...
我發(fā)出的報(bào)文怎么會亂碼?明明我設(shè)置了 utf-8 編碼的笆取!
其實(shí),這是第一個坑:httpComponents 打日志的時候希坚,把中文轉(zhuǎn)成了這種格式。其實(shí)是對的!
可憐的我在這個坑里轉(zhuǎn)了好久才發(fā)現(xiàn)翱艘痢华坦!
最后找了半天,通過抓包才終于發(fā)現(xiàn)犁跪,發(fā)送、接收到的中文報(bào)文都沒問題坷衍,但是我解出來的中文亂碼了。折騰半天后才發(fā)現(xiàn)乏矾,遠(yuǎn)程服務(wù)器返回時迁杨,沒返回編碼,而我獲取包體的代碼是用的 EntityUtils :
CloseableHttpResponse httpResponse = httpClient.execute(get);
HttpEntity httpResponseEntity = httpResponse.getEntity();
String s = EntityUtils.toString(httpResponseEntity);
似乎沒問題扒π!但是,這就是個大坑了坯钦,httpComponents 的默認(rèn)代碼并非 utf-8!
于是這個 s 就亂了……
正確的寫法其實(shí)是
EntityUtils.toString(httpResponseEntity, "utf-8");
順便說一下吟温,以前我突颊、還有我同事都踩過的一個坑。
EntityUtils.toString(httpResponseEntity, "utf-8");
這行代碼在 http 請求時必須調(diào)用爬橡!或者說棒动,返回的包體流必須被讀完。即使返回的不是 200 OK船惨!
以前由于對返回的包體內(nèi)容不關(guān)心,所以沒調(diào)疙挺。然后第一個請求可以成功怜浅,而第二個請求就卡住……
更坑的是 200 OK的時候讀包體流,而錯誤的時候直接拋異常或者返回了舱殿。然后程序工作看起來正常险掀,但時不時的卡啊卡……