JavaWeb多種亂碼解決方法

1、Servlet輸出亂碼html

1. 用servlet.getOutStream字節流輸出中文,假設要輸出的是String str ="***是中國的,無恥纔是日本的"。java

          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的響應輸出字節流與字符流是衝突的,只能用其一。cookie

2、Servlet文件下載,中文亂碼狀況。app

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

[java]  view plain copy
  1. //獲取文件的URL地址  
  2. String realPath = getServletContext().getRealPath("/***是中國的無恥纔是日本的歷史證據.jpg");  
  3. //獲取文件名: ***是中國的無恥纔是日本的歷史證據.jpg  
  4. String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);  
  5. //指示響應流的類型不是text/html而是二進制流數據以指示下載  
  6. response.setContentType("application/octet-stream");  
  7. //注意這裏通常都用URLEncoder的encode方法進行對文件名進行編碼  
  8. String enFileName = URLEncoder.encode(fileName, "utf-8");    
  9. //enFileName文件名若含有中文必須用URLEncoding進行編碼  
  10. response.setHeader("content-disposition""attachment;filename="+enFileName);  
  11. //文件讀取與輸出,模板代碼了...  
  12. InputStream in = new FileInputStream(realPath);  
  13. OutputStream out = response.getOutputStream();  
  14. int len = -1;  
  15. byte[] buf = new byte[1024];  
  16. while((len=in.read(buf))!=-1){  
  17.     out.write(buf, 0, len);  
  18. }  
  19. in.close();  


3、Servlet的response增長addCookie,cookie中value的中文碼問題解決方法。url

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

具體代碼示例以下:

[java]  view plain copy
  1. response.setContentType("text/html;charset=utf-8");  
  2. request.setCharacterEncoding("utf-8");  
  3. String getUserName = request.getParameter("username");  
  4. PrintWriter out = response.getWriter();  
  5. String username = null;  
  6. //獲取客戶端提交過來的cookie數組。  
  7. Cookie[] cookies = request.getCookies();  
  8. for (int i = 0; cookies != null && i < cookies.length; i++) {  
  9.     //遍歷cookie數組,找到含有username的key的cookie。  
  10.     if (Constant.USER_INFO.equals(cookies[i].getName())) {  
  11.         username = cookies[i].getValue();  
  12.         //獲得cookie的值後必須,進行Base64解碼,由於前次生成cookie時,value是通過Base64編碼。  
  13.         username = Base64Coder.decode(username);  //進行Base64解碼  
  14.     }  
  15. }  
  16.   
  17. out.print(username + ",恭喜您登陸成功......"+getUserName); //username從Cookie中得出來,getUserName從請求參數中  
  18. System.out.println(username+"------------");  
  19. String remember = request.getParameter("remember");  
  20. //中文必需要進行 base64進行加碼,才能做爲cookie的值  
  21. getUserName = Base64Coder.encode(getUserName);   
  22. //將編碼後的中文username的做爲cookie的value  
  23. Cookie cookie = new Cookie(Constant.USER_INFO, getUserName);  
  24. cookie.setPath(getServletContext().getContextPath());  
  25. if(null != remember){  //若選擇中了,則將Cookie寫進去,若沒有選擇中,則將之前的Cookie都置成空  
  26.     cookie.setMaxAge(Integer.MAX_VALUE); //設置Cookie是Integer最大數,好似有70多年的存效吧。呵呵  
  27. }else{  
  28.     cookie.setMaxAge(0); //設置成cookie立刻失效,maxAge是cookie的存活時間  
  29. }  
  30. response.addCookie(cookie);  


4、獲取請求參數亂碼

GET方式的亂碼:

<a href=」/demo5/servlet/RD2?name=中國」>CN,直接用request.getParameter獲得的字符串strCN將會亂碼,這也是由於GET方式是用httpurl傳過來的默認用iso-8859-1編碼的,因此首先獲得的strCn要再用iso-8859-1編碼獲得原文後,再進行用utf-8(看具體頁面的charset是什麼utf-8gbk)進行解碼便可。new String(strCn.getBytes(「ISO-8859-1」),「UTF-8」);

[java]  view plain copy
  1. String strCn = request.getParameter("name");  
  2. String name = new String(strCn.getBytes(「ISO-8859-1」),「UTF-8」);  

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

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

[java]  view plain copy
  1. request.setCharacterEncoding("UTF-8");  
  2. String name = request.getParameter("name");  
相關文章
相關標籤/搜索