1. 程式人生 > >GBK,UTF-8,和ISO8859-1編碼區別與get,post請求中文亂碼處理

GBK,UTF-8,和ISO8859-1編碼區別與get,post請求中文亂碼處理

1.編碼基礎知識  

       最早的編碼是iso8859-1,和ascii編碼相似。但為了方便表示各種各樣的語言,逐漸出現了很多標準編碼,重要的有如下幾個。 

1.1. iso8859-1 通常叫做Latin-1

      最多能表示的字元範圍是0-255,應用於英文系列。比如,字母a的編碼為0x61=97。 

      很明顯,iso8859-1編碼表示的字元範圍很窄,無法表示中文字元。但是,由於是單位元組編碼,和計算機最基礎的表示單位一致,所以很多時候,仍舊使用iso8859-1編碼來表示。而且在很多協議上,預設使用該編碼。比如,雖然"中文"兩個字不存在iso8859-1編碼,以gb2312編碼為例,應該是"d6d0 cec4"兩個字元(java字元佔2個位元組),使用iso8859-1編碼的時候則將它拆開為4個位元組來表示:"d6 d0 ce c4"(事實上,在進行儲存的時候,也是以位元組為單位處理的)。而如果是UTF編碼,則是6個位元組"e4 b8 ad e6 96 87"。很明顯,這種表示方法還需要以另一種編碼為基礎。 

2.2. GB2312/GBK 

       這就是漢字的國標碼,專門用來相容iso8859-1編碼。其中gbk是相容gb2312編碼的。 

1.3 unicode 

      這是最統一的編碼,可以用來表示所有語言的字元,而且是定長雙位元組(也有四位元組的)編碼,包括英文字母在內。所以可以說它是不相容iso8859-1編碼的,也不相容任何編碼。不過,相對於iso8859-1編碼來說,uniocode編碼只是在前面增加了一個0位元組,比如字母a為"00 61"。 

      需要說明的是,定長編碼便於計算機處理(注意GB2312/GBK不是定長編碼),而unicode又可以用來表示所有字元,所以在很多軟體內部是使用unicode編碼來處理的,比如java。 

1.4 UTF 

       考慮到unicode編碼不相容iso8859-1編碼,而且容易佔用更多的空間:因為對於英文字母,unicode也需要兩個位元組來表示。所以unicode不便於傳輸和儲存。因此而產生了utf編碼,utf編碼相容iso8859-1編碼,同時也可以用來表示所有語言的字元,不過,utf編碼是不定長編碼,每一個字元的長度從1-6個位元組不等。另外,utf編碼自帶簡單的校驗功能。一般來講,英文字母都是用一個位元組表示,而漢字使用三個位元組。 

       注意,雖然說utf是為了使用更少的空間而使用的,但那只是相對於unicode編碼來說,如果已經知道是漢字,則使用GB2312/GBK無疑是最節省的。不過另一方面,值得說明的是,雖然utf編碼對漢字使用3個位元組,但即使對於漢字網頁,utf編碼也會比unicode編碼節省,因為網頁中包含了很多的英文字元。 

2.Unicode、UTF-8 和 ISO8859-1到底有什麼區別

       將以"中文"兩個字為例,經查表可以知道其GB2312編碼是"d6d0 cec4",Unicode編碼為"4e2d 6587",UTF編碼就是"e4b8ad e69687"。注意,這兩個字沒有iso8859-1編碼,但可以用iso8859-1編碼來表示。 

3. java對字元的處理 

在java應用軟體中,會有多處涉及到字符集編碼,有些地方需要進行正確的設定,有些地方需要進行一定程度的處理。 

3.1 getBytes(charset) 

       這是java字串處理的一個標準函式,其作用是將字串所表示的字元按照charset編碼,並以位元組方式表示。注意字串在java記憶體中總是按unicode編碼儲存的。比如"中文",正常情況下(即沒有錯誤的時候)儲存為"4e2d 6587",如果charset為"gbk",則被編碼為"d6d0 cec4",然後返回位元組"d6 d0 ce c4"。如果charset為"utf8"則最後是"e4 b8 ad e6 96 87"。如果是"iso8859-1",則由於無法編碼,最後返回 "3f 3f"(兩個問號)。 

3.2 new String(charset) 

        這是java字串處理的另一個標準函式,和上一個函式的作用相反,將位元組陣列按照charset編碼進行組合識別,最後轉換為unicode儲存。參考上述getBytes的例子,"gbk" 和"utf8"都可以得出正確的結果"4e2d 6587",但iso8859-1最後變成了"003f 003f"(兩個問號)。因為utf8可以用來表示/編碼所有字元,所以new String( str.getBytes( "utf8" ), "utf8" ) === str,即完全可逆。 

3.3 setCharacterEncoding() 

該函式用來設定http請求或者相應的編碼。 

       對於request,是指提交內容的編碼,指定後可以通過getParameter()則直接獲得正確的字串,如果不指定,則預設使用iso8859-1編碼,需要進一步處理。

      參見下述"表單輸入"。值得注意的是在執行setCharacterEncoding()之前,不能執行任何getParameter()。java doc上說明:This method must be called prior to reading request parameters or reading input using getReader()。而且,該指定只對POST方法有效,對GET方法無效。分析原因,POST方法在執行第一個getParameter()的時候,java將會按照編碼分析所有的提交內容,而後續的getParameter()不再進行分析,所以setCharacterEncoding()無效。而對於GET方法提交表單是,提交的內容在URL中,一開始就已經按照編碼分析所有的提交內容,setCharacterEncoding()自然就無效。

       注意:iso-8859-1是JAVA網路傳輸使用的標準字符集,而gb2312是標準中文字符集,當你作出提交表單等需要網路傳輸的操作的時候,就需要把 iso-8859-1轉換為gb2312字符集顯示,否則如果按瀏覽器的gb2312格式來解釋iso-8859-1字符集的話,由於2者不相容,所以會 是亂碼.

例子:

String s = "你好";
// 編碼
byte[] utf = s.getBytes("utf-8");
byte[] gbk = s.getBytes("gbk");
System.out.println("utf-8編碼:" + Arrays.toString(utf));//[-28,-67,-96,-27,-91,-67]  6個位元組System.out.println("gbk編碼:" + Arrays.toString(gbk));//[-60,-29,-70,-61] 4個位元組
// 解碼 
String s1 = new String(utf, "utf-8"); // 你好S
tring s2 = new String(utf, "gbk"); // gbk解碼:浣犲ソ gbk用2個位元組解碼,所以會多一個字元
String s3 = new String(gbk, "utf-8"); // gbk用utf-8解碼:??? utf-8解碼需要6個位元組
System.out.println("--------------------");
System.out.println("utf-8解碼:" + s1);
System.out.println("gbk解碼:" + s2);
System.out.println("gbk用utf-8解碼:" + s3);
System.out.println("---------------------");
System.out.println("用utf-8編碼回去");
s3 = new String(s3.getBytes("utf-8"), "gbk"); // 錕斤拷錕?   gbk用utf-8解碼後無法編回去System.out.println(s3);

規律:

utf-8編碼可以用gbk和iso8859-1解碼後編回去

gbk編碼後只能用iso8859-1解碼後編回去

解決Get和Post請求中中文亂碼問題

 對於Post請求,只需在Servlet或者jsp中寫入如下程式碼就可以把解決從表單中傳入的中文亂碼問題

  request.setCharacterEncoding("utf-8");

而對於Get請求,因為請求引數會被附加到位址列的URL之後,所以不能用上面的處理方法。應該這樣:

   String str=request.getQueryString();

   //使用URLDecoder解碼字串

   String str1=java.net.URLDecoder.decode(str,"utf-8");

   String[] paraStrings=str1.split("&");

//paraStrings[0]就是第一個引數,依次類推...

   for(String paraString : paraStrings)

{

     String[] nameValue=paraString.split("=");

     //nameValue[0]就是表單的name,nameValue[1]就是表單name對應的值

}

還有一種方法就是獲取請求引數之後對請求引數值重新編碼,也就是先將其轉換成位元組陣列,再將位元組陣列重新解碼成字串。

  String str=request.getParameter("name");

  byte[] bytes=str.getBytes("ISO-8859-1");

  String name=new String(bytes,"utf-8");

相關推薦

GBK,UTF-8,ISO8859-1編碼區別get,post請求中文亂碼處理

1.編碼基礎知識          最早的編碼是iso8859-1,和ascii編碼相似。但為了方便表示各種各樣的語言,逐漸出現了很多標準編碼,重要的有如下幾個。  1.1. iso8859-1

Python中GBK, UTF-8Unicode的編碼問題

https://www.cnblogs.com/jxzheng/p/5186490.html 編碼問題,一直是使用python2時的一塊心病。幾乎所有的控制檯輸入輸出、IO操作和HTTP操作都會涉及如下的編碼問題: UnicodeDecodeError: ‘ascii’ codec can’

Unicode、UTF8 ISO8859-1到底有什麽區別

string ram 第一個 不存在 ring 如果 提交表單 3.2 tro 說明:本文轉載於新浪博客,旨在方便知識總結。原文地址:http://blog.sina.com.cn/s/blog_673c81990100t1lc.html 本文主要包括以下幾個方面:編碼

JAVA 編碼中文問題系統透徹講解 UNICODE GBK UTF-8 ISO-8859-1 之間的區別

宣告 目錄 步驟 1 : 編碼概念 步驟 2 : 常見編碼 步驟 3 : UNICODE和UTF 步驟 4 : Java採用的是Unicode 步驟 5 : 一個漢字使用不同編碼方式的表現 步驟 6 : 檔案的編碼方式-記事本 步驟 7 : 檔案的編碼方式-e

java中new String(str.getBytes(“utf-8”),“iso-8859-1”)編碼詳解

前提是str存放的是漢字一、如果是new String(str.getBytes(“gbk”),“gbk”)時,可以分為兩步:      第一步:byte[] bytes=str.getBytes(“gbk”)        告訴java虛擬機器將中文以“gbk”的方式轉換為

JSP-tomcat設定編碼格式 配置utf-8(以防網頁框以及網頁顯示的時候中文亂碼

JSP-tomcat設定編碼格式 配置utf-8(以防網頁框以及網頁顯示的時候中文亂碼) 關鍵詞: tomcat配置utf-8 解決網頁中文亂碼 tomcat中server.xml配置編碼格式 jsp中設定了charset是UTF-8,但瀏覽器仍然顯示亂碼

axios服務封裝,可用於任何支援axios的專案中,包括reactvue都可通用。get/post請求,以及併發請求。以及導航欄隨意切換測試/正式環境

任何專案,只要支援axios,那麼你只要把我現在封裝的服務整個資料夾考過去即可。這個原本是我封裝在vue裡的,但是有一天公司突然來一個緊急的H5微信分享活動的專案,我當時用react搭建(zepto+node搭建其實最好)也是為了挑戰一下自己,畢竟只有三天時間。所以當我把很多vue裡封裝的東西直

更改Tomcat字元編碼設定及解決post請求中文字元亂碼

我遇到這個問題的時候是在做一個第三方支付介面的時候,在回撥函式中,解碼URL的時候怎麼解都不好使,解出來是亂碼的問題,搞了半天沒解決,百度找到了另一種方法。 這是第一種方法 new String(getURLDecoderString(json).getBytes("IS

關於java程式碼提交HTTP POST請求中文亂碼的解決方法 HttpURLConnectionHttpClient比較使用示例

首先說明下這些只是根據我工作常用經驗的總結,可能不一定完全對,也不一定全面,但卻是最通用的。 JAVA裡HTTP提交方式 httpurlconnection:jdk裡自帶的 httpclient:apache開源專案 resttemplate:spring提供,本質就是封裝了httpclie

關於getpost請求中文亂碼的解決辦法

web專案中經常遇到中文亂碼問題,本文簡單記錄遇到中文亂碼問題時的解決方案,程式碼如下: <form class="form-horizontal" role="form" action="${pageContext.request.contextPath}/add

UTF-8GBK編碼之間的區別(頁面編碼、數據庫編碼區別)以及在實際項目中的應用

同方 截斷 擴展 字節 文章 ech shu 基礎上 頁面 第一節:UTF-8和GBK編碼概述 UTF-8 (8-bit Unicode Transformation Format) 是一種針對Unicode的可變長度字符編碼,又稱萬國碼,它包含全世界所有國家需要用到的字符

UTF-8GBK編碼區別

需要 div 字符 英文 世界 body utf8 nbsp 使用 UTF-8:對英文使用8位(一個字節)、中文使用24位(三個字節)編碼。對於英文字符比較多的網站一般用utf-8來編碼以節省空間;包含全世界所有國家需要用到的字符,其編碼的蚊子可以在各國各種支持utf8字符

編碼歷史ASCII、Unicode、utf-8GBK

英文字母 英文 全世界 兩個 編碼 中國 歷史 1的個數 包含 ASCII編碼:用來表示所有的大寫和小寫字母,數字0 到9、標點符號, 以及在美式英語中使用的特殊控制字符,一個字符共8位,占一個字節。 ASCII編碼是由美國國家標準協會制定的標準的單字節字符編碼方案,用來存

UTF-8GBK區別

   字元均使用雙位元組來表示,只不過為區分中文,將其最高位都定成1。   至於UTF-8編碼則是用以解決國際上字元的一種多位元組編碼,它對英文使用8位(即一個位元組),中文使用24位(三個位元組)來編碼。對於英文字元較多的論壇則用UTF-8節省空間。&n

JAVA 漢字在UTF-8GBK編碼中佔用位數

       做JAVA開發好久了,發現好多基礎的東西竟然還是不知道,平時也沒有寫筆記的習慣,就用CSDN來做簡單的筆記記錄吧,以供以後來查詢筆記。         JAVA的字元編碼中有兩種常用的字符集:GBK和U

python中文編碼問題(decode('gbk').encode('utf-8')decode('utf-8').encode('gbk')這對好基友)

    想必每個Python新手都會遇到Python編碼的問題,特別是使用到漢字的時候。UTF-8編碼是比較通用的編碼方式,它可以輸出中文,而Python2中預設的編碼方式一般是GBK,所以往往我們期

utf-8unicode的區別:字元編碼的辨析

總的來說就是一句話:utf-8是變長的,作為檔案儲存時用,unicode是定長的,將檔案讀取到記憶體時用 我們已經講過了,字串也是一種資料型別,但是,字串比較特殊的是還有一個編碼問題。 因為計算機只能處理數字,如果要處理文字,就必須先把文字轉換為數字才能處理。最早的計

UTF-8GBK有什麼區別

GBK是在國家標準GB2312基礎上擴容後相容GB2312的標準(好像還不是國家標準)。GBK編碼專門用來解決中文編碼的,是雙位元組的。不論中英文都是雙位元組的。 UTF-8 編碼是用以解決國際上字元的一種多位元組編碼,它對英文使用8位(即一個位元組),中文使用24位(三

為什麼需要編碼UTF-8GBK是如何進行編碼

編碼是為了在資料傳輸的過程中節省資料儲存空間,可以節省頻寬,加快傳輸速度。UTF-8:英文一個位元組,中文3個位元組。它可以使用1~4個位元組表示一個符號GBK:英文兩個位元組,中文2個位元組。UTF-8 是 Unicode 的實現方式之一。我們已經知道,英文字母只用一個位元

utf-8Unicode的區別

shu 中國人 gbk sci 都對 編碼方式 過去的 view 關系 鏈接 utf-8和Unicode到底有什麽區別?是存儲方式不同?編碼方式不同?它們看起來似乎很相似,但是實際上他們並不是同一個層次的概念 要想先講清楚他們的區別,首先應該講講Unicode的來由。