目前在寫一個功能,主要是使用 HttpURLConnection 發送http請求調用外部接口。本來一切正常的,可是在發送post請求上傳數據給服務端時,服務端返回錯誤信息:獲取的JSON請求是亂碼的。
因為請求的 JSON 里面包含了中文,所以一開始我把思路鎖定在了編碼問題,這樣就走進了死胡同。在把tomcat、JDK、請求頭的 header 中的 Content-Type 全都排查了一遍后,確認都是utf-8編碼呀,
為什么還會出現亂碼?熟練地打開了百度,但是一眼望去都是各種教你改 http 請求頭的,或者如下:
DataOutputStream out = null; out = new DataOutputStream(connection.getOutputStream()); //out.writeBytes(content); out.write(content.getBytes());
把 out.writeBytes(content) 換成 out.write(content.getBytes()) ,因為 java 里的 char 類型是16位(2個字節)的,一個 char 可以存儲一個中文字符,在將其轉換為 byte(1個字節)后高8位會丟失,這樣就無法將中文字符串完整的輸出到字節輸出流中。所以在可能有中文字符輸出的地方最好先將字符串轉換為字節數組,然后再通過 write() 寫入字節輸出流。
但是,這種方法只對有的人的問題生效,沒有解決我的問題。直到我看到了這篇博客 https://blog.csdn.net/hwj3747/article/details/53635539
PrintWriter out = null; out = new PrintWriter(new OutputStreamWriter(connection.getOutputStream(),"utf-8")); out.println(content);
思路是用字符流代替字節流進行傳輸,因為我們傳入的JSON字符串是純字符。這樣就完美避開了用字節流傳輸包含中文的字符串可能存在的各種轉化問題。
總結:因為長期在寫業務代碼,所以對Java底層流機制非常生疏了。