1. 程式人生 > >JavaWeb的各種中文亂碼終極解決方法

JavaWeb的各種中文亂碼終極解決方法

一、Servlet輸出亂碼

1. 用servlet.getOutStream位元組流輸出中文,假設要輸出的是String str ="釣魚島是中國的,無恥才是日本的"。

1.1 若是本地伺服器與本地客戶端這種就不用說了,直接可以out.write(str.getBytes())可以輸出沒有問題。因為伺服器中用str.getBytes()是採用預設本地的編碼,比如GBK。而瀏覽器也解析時也用本地預設編碼,兩者是統一的,所以沒有問題。

1.1 若伺服器輸出時用了, out.write(str.getBytes("utf-8"))。而本地預設編碼是GBK時(比例在中國),那麼用瀏覽器開啟時就會亂碼。因為伺服器傳送過來的是utf-8的1010資料,而客戶端瀏覽器用了gbk來解碼,兩者編碼不統一,肯定是亂碼。當然,你也可以自己將客戶端瀏覽器的編碼手工呼叫下(IE選單是:查詢View->編碼encoding->utf-8),但是這種操作很爛,最好由伺服器輸出響應頭告訴,瀏覽器用哪種編碼來解碼。所以要在伺服器的servlet中,增加response.setHeader("content-type","text/html;charset=utf-8"),當然也可直接用簡單的response.setContentType("text/hmtl;charset=utf-8")。兩種的操作是一樣一樣的。

2. 用servlet.getWirter字元流輸出中文,假設要輸出的是String str ="釣魚島是中國的,無恥才是日本的"。

2.1 若寫成out.print(str)輸出時,客戶端瀏覽器顯示的將全是多個?????的字元,代表在編碼表中肯定就找不到相應的字元來顯示。原因是:servlet.getWriter()得到的字元輸出流,預設對字元的輸出是採用ISO-8859-1,而ISO-8859-1肯定是不支援中文的。所以肯定要首先要做的第一件事:是要將伺服器物件輸出字元能支援中文的。其次伺服器向客戶端寫回的響應頭要告訴客戶端是用了哪種編碼表進行編碼的。而實現這兩個需求,只需要response.setContentType("text/hmtl;charset=utf-8")。就搞定了。特別注意:response.setContentType("text/html;charset=utf-8")要放在PrintOut out = response.getWriter()程式碼的前面,否則只是有告訴客戶端用什麼碼錶編碼的功能,而伺服器端還是用ISO-8859-1編碼了。再特別提示下:在同一Servlet中的doGet或doPost方法中,不能既用response.getOutputStream又用response.getWriter,因為這兩種response的響應輸出位元組流與字元流是衝突的,只能用其一。

二、Servlet檔案下載,中文亂碼情況。

關鍵是下載時響應頭 content-disposition中attachment;filename=檔名。這個檔名filename不能是含有中文字串的,要用URLEncoding編碼進行編碼,才能進行進行http的傳輸。如下程式碼示例:

 

三、Servlet的response增加addCookie,cookie中value的中文碼問題解決方法。

關於cookie的原理,見http://blog.csdn.net/chenshufei2/article/details/8009992。 若想將cookie中存放中文的值,必須用Base64編碼後,發給客戶瀏覽器端進入儲存。而下次客戶端瀏覽訪問是帶回來的cookie中的值,是經過Base64編碼的,所以需要用Base64解碼即可。 Base64編碼主要是解決將特殊字元進行重新編碼,編碼成a-b、A-B、0-9、+與/,字元52,10個數字與一個+,一個/ 共64個字元。它的原理是將原來3個位元組的內容編碼成4個位元組。主要是取位元組的6位後,在前面補00組成一個新的位元組。所以這樣原來的3個位元組共24,被編碼成4個位元組32位了。

具體程式碼示例如下:

 

四、獲取請求引數亂碼

GET方式的亂碼:

如<a href=”/demo5/servlet/RD2?name=中國”>CN</a>,直接用request.getParameter得到的字串strCN將會亂碼,這也是因為GET方式是用http的url傳過來的預設用iso-8859-1編碼的,所以首先得到的strCn要再用iso-8859-1編碼得到原文後,再進行用utf-8(看具體頁面的charset是什麼utf-8或gbk)進行解碼即可。new String(strCn.getBytes(“ISO-8859-1”),“UTF-8”);

這種方式操作比較麻煩的是,有一個引數要用iso-8859-1編碼一次再解碼一次。

POST方式的亂碼:只需要request.setCharacterEncoding("UTF-8"):即可。