亂碼問題總結

亂碼問題總結

一、Response發送數據時可能導致亂碼:

  1、Response.getOutputStream().write("中國".getBytes()) ;

      這裡默認用平台位元組碼進行編碼,發送給瀏覽器(瀏覽器默認的也 是用平台位元組碼進行編碼)。如果瀏覽器不是使用默認的編碼格式(如果使用 utf-8),那麼在輸出數據時也要選擇要使用的編碼格式進行編碼:

        response.getOutputStream().write("中國".getBytes("utf-8")) ;

  2、response.getWriter().write("中國");

      這裡默認使用iso-8859-1 編碼集進行編碼,所以使用該方法最容易 導致亂碼,在使用字元流輸出數據時,要在獲取字元流對象前手動進行編碼 設置:         response.setContentType("text/html;Charset=utf-8") ; 或者: response.setCharacterEncoding("gbk") ;

              |——注意:使用response.setCharacterEncoding("gbk") ;時 設置的編碼格式和系統默認的則只需要上述一條語句。

                    否則還要加上: response.setCharacterEncoding("utf-8") ;

                              response.setHeader("Content-Type", "text/html;Charset=utf-8");

      所以:為了方便一般設置:response.setContentType("text/html;Charset=utf-8") ;即可

二、Request 獲取請求參數時可能導致亂碼:

      瀏覽器發送的請求參數使用的編碼就是打開網頁時使用的編碼,而服 務器獲取發送過來的請求參數默認使用 ISO-8859-1 進行解碼操作,所以這過 程中可能導致亂碼:

      1、對於Post方式提交的數據:

      可以設置request.setCharacterEncoding("utf-8");來明確指定獲取 參數時使用的編碼,但是此種方法只對Post 方式提交的數據有用;即是只對 請求體有用。

      2、對於Get方法提交的數據:

      只能手動解決亂碼: String str = new String(name.getBytes("ISO8859-1"),"gbk") ;

      3、通過配置tomcat的servlet.xml 配置:

      在tomcat的server.xml中可以配置http連接器的URIEncoding可以指定 伺服器在獲取請求參數時默認使用的編碼,從而一勞永逸的決絕獲取請求參數時 的亂碼問題。也可以指定useBodyEncodingForURI參數,令request.setCharacterEncoding也 對GET方式的請求起作用,但是這倆屬性都不推薦使用,因為發布環境往往不允許修改此屬性。

三、URL中包含中文時可能出現亂碼:

    解決方法URL編碼:

    1、由於HTTP協議規定,URL路徑只能存在ASCLL碼中的字元,所以如果URL中存在中文或特殊字元需要進行URL編碼。

     2、編碼原理:

        將空格轉換為加號(+)

         對0-9,a-z,A-Z之間的字元保持不變

         對於所有其他的字元,用這個字元的當前字符集編碼在內存中的十六進位格式表示,並在每個位元組前加上一個百分號(%)。如字元「+」用%2B表示,字元「=」用%3D表示,字元「&」用%26表示,每個中文字元在內存中佔兩個位元組,字元「中」用%D6%D0表示,字元「國」用%B9%FA表示調對於空格也可以直接使用其十六進位編碼方式,即用%20表示,而不是將它轉換成加號(+)

         說明:

          如果確信URL串的特殊字元沒有引起使用上的岐義或衝突你也可以對這些字元不進行編碼,而是直接傳遞給伺服器。例如,http://jbelial.cnblogs.com?name=中國&password=123

          如果URL串中的特殊字元可能會產生岐義或衝突,則必須對這些特殊字元進行URL編碼。

          例如,伺服器會將不編碼的「中+國」當作「中國」處理。還例如,當name參數值為「中&國」時,如果不對其中的「&」編碼,URL字元串將有如下形式:http://jbelial.cnblogs.com?name=中&國&password=123,應編碼為:http://jbelial.cnblogs.com?name=中%26國&password=123 http://jbelial.cnblogs.com/index.html#section2可改寫成http://jbelial.cnblogs.com%2Findex.html%23section2

     3、在Java中進行URL編碼和解碼: URLencoder.encode("中文","utf-8") ; URLDecoder.decode(str,"utf-8") ;

四、JSTL : c:redircet 標籤內的 c:param 標籤自動編碼後,在重定向頁面要進行手動解碼。

  

五、在往資料庫存入數據時,往外裡面存儲數據會出現亂碼:

mysql > show variables like "charact%" ;

+--------------------------+---------------------------------------------------------+

| Variable_name | Value |

+--------------------------+---------------------------------------------------------+

| character_set_client | utf8 |

| character_set_connection | utf8 |

| character_set_database | utf8 |

| character_set_filesystem | binary |

| character_set_results | utf8 |

| character_set_server | utf8 |

| character_set_system | utf8 |

| character_sets_dir | C:Program FilesMySQLMySQL Server 5.0sharecharsets |

+--------------------------+---------------------------------------------------------+

原因:在安裝資料庫時,我們選擇的是默認為utf-8 編碼集;所以,資料庫伺服器,默認我們寫入數據時即客戶端也是用的utf-8 編碼集;所以當客戶端gbk進行編碼,而伺服器則以utf-8編碼進行解碼,所以會出現亂碼。

解決辦法:

    1、set names 當前客戶端編碼集;

    2、主要是解決:character_set_client ,character_set_connection 該兩個欄位名的值。

      set character_set_client gbk ;

      set character_set_connection gbk ;

character_set_results 則是設置dos端顯示的編碼集。

-------------------------------------------------------------------------------更新時間:2013年7月11日 19:25:57

六、對全站中文亂碼問題的解決辦法——Filter

  

1 import java.io.IOException; 2 3 import javax.servlet.Filter; 4 import javax.servlet.FilterChain; 5 import javax.servlet.FilterConfig; 6 import javax.servlet.ServletException; 7 import javax.servlet.ServletRequest; 8 import javax.servlet.ServletResponse; 9 import javax.servlet.http.HttpServletRequest;10 import javax.servlet.http.HttpServletResponse;11 /**12 * 全站同一編碼13 * @author 賀佐安14 *15 */16 public class SetCharacterEncoding implements Filter {17 private FilterConfig filterConfig = null ;18 //獲取初始化的FilterConfig對象19 public void init(FilterConfig filterConfig) throws ServletException {20 this.filterConfig = filterConfig ;21 }22 23 public void doFilter(ServletRequest req , ServletResponse resp ,24 FilterChain chain) throws IOException, ServletException {25 HttpServletRequest request = (HttpServletRequest) req ; 26 HttpServletResponse response = (HttpServletResponse) resp ;27 28 //獲取初始化的字元編碼29 String encoding = filterConfig.getInitParameter("Encoding") ;30 request.setCharacterEncoding(encoding) ;31 response.setCharacterEncoding(encoding) ; 32 response.setContentType("text/html;charset="+encoding) ;33 34 MyHttpServletRequest myRequest = new MyHttpServletRequest(request) ;35 chain.doFilter(myRequest, response) ;36 }37 38 public void destroy() {39 40 }41 }

  在設置同一編碼時,不要把編碼寫死,寫在配置文件中。當然,要用Filter 進行過濾的話要對HttpServletRequest 介面進行包裝:目的是解決get方式提交也不會出現亂碼問題。

  代碼如下:

1 import java.io.UnsupportedEncodingException; 2 3 import javax.servlet.http.HttpServletRequest; 4 import javax.servlet.http.HttpServletRequestWrapper; 5 /** 6 * 包裝HttpServletRequest 類,為了解決全站亂碼問題 7 * @author 賀佐安 8 * 9 */10 public class MyHttpServletRequest extends HttpServletRequestWrapper {11 public MyHttpServletRequest (HttpServletRequest request) {12 super(request) ;13 }14 15 //對getParameter方法進行修飾: 主要是為了解決用戶使用get方式提交的情況16 public String getParameter(String name) {17 //如果是get方法則手動解碼18 if("get".equalsIgnoreCase(super.getMethod())) {19 String value = super.getParameter(name) ;20 try {21 return new String (value.getBytes("ISO-8859-1"),super.getCharacterEncoding()) ;22 } catch (UnsupportedEncodingException e) {23 e.printStackTrace();24 }25 }26 return super.getParameter(name);27 }28 }

  當然還要不要忘記配置web.xml:

1 <!-- 全站中文亂碼過濾器:開始 --> 2 <filter> 3 <filter-name>SetCharacterEncoding</filter-name> 4 <filter-class>filter.SetCharacterEncoding</filter-class> 5 <!-- 設置全站的編碼--> 6 <init-param> 7 <param-name>Encoding</param-name> 8 <param-value>UTF-8</param-value> 9 </init-param>10 </filter>11 <filter-mapping>12 <filter-name>SetCharacterEncoding</filter-name> 13 <url-pattern>/*</url-pattern>14 </filter-mapping>15 <!-- 全站中文亂碼過濾器:結束 -->


推薦閱讀:

所有人都必須深思的重大問題
王開東:打與不打,是個問題
長期服用美托洛爾需要注意哪些問題?
LC信用證經典問題
封面|孩子扁平足,竟然可能帶來這麼多問題,矯正只需要一個鞋墊……內附醫訊

TAG:亂碼 | 總結 | 問題 |