開發中常見的編碼和亂碼問題

以漢字‘中國’爲例html

咱們常常在開發中會遇到以下幾種java

  • \u4e2d\u56fd
  • %E4%B8%AD%E5%9B%BD
  • 中国 中国

從這裏幾個編碼開始提及吧web

1 unicode字符串

    \u4e2d\u56fd  ,咱們常常在後臺的配置文件中看到,好比message 文件,它表示的字符在unicode編碼中對應的數字。spring

    因爲java內部採用unicode編碼,能夠經過下面的代碼來獲取。瀏覽器

String str1 = "\u4e2d\u56fd";
System.out.println(str1);
System.out.println(Integer.toHexString('中'));

輸出
中國
4e2d

 

2 URL Encoder

%E4%B8%AD%E5%9B%BD, 這類編碼 ,常常在get請求的url中看到,用於傳遞表單數據,顯示的數據實際上就是字符的UTF-8的值,每一個字節前加上%tomcat

經過以下代碼來驗證網絡

byte[] aa = "中國".getBytes("utf-8");
for(int i=0; i<aa.length;i++)
{
    System.out.print(String.format("%02x",aa[i]).toUpperCase());
}

輸出
E4B8ADE59BBD

看到這裏,可能會有一個疑惑,就是unicode怎麼轉換爲utf-8的,4e2d怎麼變成E4B8AD的,下面來講說這個問題。字體

3 unicode和utf-8

unicode是編碼方案,4e2d 描述的是‘中’在編碼表對應的數字,但並不涉及如何在字節中展現它。ui

utf的的全稱(Unicode Transformation Formats),從字面能夠理解,它描述的是unicode編碼在字節中的存儲了。編碼

UTF-8 規則以下

  1. 對於ascii字符,第一位爲0,後面的x由ascii來填充

        0xxxxxxx

        這樣作的好處是,utf-8向下兼容ascii編碼。

  2.   對於其餘字符,經過可變字節來表示

           第一個字節前n位設置爲1,第n+1位設置爲0 ,後面字節前2爲都設置爲10,其餘空餘位 由unicode          編碼來填充,高位補0

110xxxxx 10xxxxxx
1110xxxx 10xxxxxx 10xxxxxx
11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

拿剛纔的中的例子來講

4E2D轉換爲二進制位爲                     0100111000101101

在UTF-8中須要使用3個字節來表示    1110xxxx 10xxxxxx 10xxxxxx

將4E2D填充到x中後  表示爲              11100100 10111000 10101101

轉換爲十六進制爲  E4B8AD

 

4 html字符實體

&#20013;&#22269; &#x4E2D;&#x56FD; 這種很少見,實際上也就是unicode的值,它本質我理解爲html的轉義字符,咱們可能會在html中看到它。20013  4E2D 就是十進制和十六進制,其實都是同樣的。

 

5 亂碼的產生

    咱們知道,一個字節範圍是0-255,ascii在表示字符時,使用了0-127。而中文字符因爲數量多,須要由兩個以上的字節去表示一個字符。

    每種編碼集,都將字符映射到了不一樣的字節去表示,好比港臺的BIG5 大陸的GBK,國際規範的unicode等。之前有款軟件叫作magicwin,基本98,95下玩遊戲必備,就是轉換字體的字符集的。

    咱們開發中,出現亂碼常常是IO環節出現,好比讀寫文件,網絡通信等。

    實際上這個過程經歷了 String ->byte -> String。

    好比咱們在通信或文件操做時,傳輸和保存的本質都是字節流,而在字符到字節轉換的過程當中,須要按照一致的編碼解碼進行處理,不然就會產生亂碼

以下圖所示

  

上圖就是  gbk編碼的中國  在解碼時被轉換成了亂碼

須要注意的幾點

  1. 避免屢次編碼或解碼。
  2. 注意操做系統、虛擬機環境的默認編碼

 

6 WEB環境下的亂碼

WEB環境下,主要是瀏覽器->TOMCAT容器->具體項目代碼

出現亂碼可能在如下兩個點

  1. 表單提交的數據產生亂碼
  2. 網頁顯示亂碼

WEB環境下亂碼的本質是網絡IO的亂碼,瀏覽器是客戶端,而 tomcat是服務端,產生的緣由對應以下:

  1. 當瀏覽器提交的數據,後臺解碼不正確時,後臺會產生亂碼
  2. 當瀏覽器解析後臺返回的數據時,編碼解碼不一致,網頁可能會顯示亂碼。

主要因爲涉及到瀏覽器,容器之類的,形成對於編碼不太透明,會讓人疑惑。

常見的處理方式:

  1.  get請求的亂碼

        瀏覽器在發起get請求時,會進行encodeURI,將漢字轉換爲%E4%B8%AD%E5%9B%BD, 而tomcat在默認解析時,會按照iso8859-1去處理,因此常常會出現一些request.getParameter() 獲取的字符串爲亂碼。

        這個處理最好全局的去修改tomcat  的配置文件爲URIEncoding="UTF-8" ,不然須要對字符串進行一個iso8859-1 -> utf-8的轉換。

  2. 網頁顯示的字符集設置

    網頁在解析html文件時,會按照聲明的字符集進行解析

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    若是不設置,會自動選擇字符集進行處理,每一個瀏覽器默認的不一致。 

    保持聲明的一致就能夠避免亂碼

  3. POST請求的亂碼

        常見的方式 設置統一的filter 進行處理。

 <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>

相關文章
相關標籤/搜索