漂洋過海

          漂洋過海
          數據加載中……
          java 的字符編碼問題

          java 的字符編碼問題-2  

          2008-11-17 11:01:23|  分類: JSP,JAVA,C等相關 |  標簽: |字號 訂閱

          二、JAVA 對字符的處理
              1. getBytes(charset)
                 
                  這是 java 字符串處理的一個標準函數,其作用是將字符串所表示的字符按照 charset 編碼,并以字節方式表示。注意字符串在 java 內存中總是按 unicode 編碼存儲的。
              Java程序從輸入流、文件或字符文字量等途徑獲得字符串時,均會做字符編碼的轉換,例如InputStreamReader 的構造函數中就需要指定編碼方式,而對于從文件和字符文字量中獲得字符串時,均采用系統默認的編碼方式對字符數據進行解碼。考慮下面一段代碼:

          String str=””;

          byte[] bytes = str.getBytes();

          bytes = str.getBytes(“ISO-8859-1”);

          語句①:將一個只含有一個字符的字符串文字量賦給 String 類的一個對象 str,字符文字量是按照操作系統默認編碼方式進行編碼,在中文 windows 系統中通常是“GBK”,“中”在GBK編碼中是0xD6D0,在將該字符賦給str時,Java會對該字符串進行編碼轉換,即將GBK編碼方式的“中”轉換成Unicode編碼方式的“中”,Unicode編碼方式“中”的編碼是0x4E2D,所以str在程序運行期間在內存中的二進制表示成16進制就是0x4E2D

          語句②:獲得str字符串的二進制形式。getBytes(String encoding)方法需要指定編碼方式,表示獲得該字符串在何種編碼方式中的二進制形式。此語句中沒有設置參數,表示采用操作系統默認的編碼方式,即此處獲得的bytesGBK編碼中的二進制形式,即bytes[0]=0xD6, bytes[1]=0xD0

          語句③:該語句與語句②的區別就是指定了編碼方式,此處指定的是ISO-8859-1,即通常所說的Latin-1,該編碼采用8bit對字符編碼,所以編碼空間中只有256個字符。該編碼中只包含了基本的ASCII碼和一些擴展的其它西歐字符,所以該字符集中不可能包含中文的“中”字,也就是說Java虛擬機無法在ISO-8859-1編碼集中找到“中”字對應的編碼,針對這種情況,就只返回一個問號(?,0x3f)字符,所以此時bytes.length只有1,且bytes[0]=0x3f

          2.new String(byte[] bytes, String encoding)

          getBytes()方法從字符串獲得二進制的字節數組。如果要從二進制的字節數組獲得字符串,則就需要使用new String(byte[] bytes, String encoding)方法,該方法按照encoding編碼方法對字節數組bytes中的二進制數組進行解析,生成一個新的字符串對象。

          byte[] bytes = {(byte)0xD6, (byte)0xD0, (byte)0x31};

          String str = new String(bytes);

          str = new String(bytes,”ISO-8859-1”);

           

          語句①:定義一個字節數組。

          語句②:將該字節數組中的二進制數據按照默認的編碼方式(GBK)編碼成字符串,我們知道GBK0xD6 0xD0表示“中”,0x31表示字符“1”(GBK兼容ASCII,但不兼容ISO-8859-1ASCII之外的部分),所以str得到的值是“中1”。

          語句③:該句用ISO-8859-1編碼方式對該字節數據進行編碼,由于在ISO-8859-1編碼方式中一個字節會被解析成一個字符,所以該字節數組會被解釋成包含三個字符的字符串,但由于在ISO-8859-1編碼方式中沒有對應0xD60xD0的字符,所以前兩個字符會產生兩個問號,由于0x31ISO-8859-1編碼中對應字符“1”(ISO-8859-1也兼容ASCII),所以此語句得到str的值是“??1”。

          3.setCharacterEncoding()

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

          對于request,是指提交內容的編碼,指定后可以通過getParameter()直接獲得正確的字符串,如果不指定,則默認使用iso8859-1 編碼,需要進一步處理。值得注意的是在執行setCharacterEncoding()之前,不能執行任何 getParameter()而且,該指定只對POST方法有效,對GET方法無效。分析原因,應該是在執行第一個getParameter()的時候,java將會按照編碼分析所有的提交內容,而后續的getParameter()不再進行分析,所以setCharacterEncoding()無效。而對于GET方法提交表單時,提交的內容在URL中,一開始就已經按照編碼分析所有的提交內容,setCharacterEncoding()自然就無效。

          對于response,則是指定輸出內容的編碼,同時,該設置會傳遞給瀏覽器,告訴瀏覽器輸出內容所采用的編碼。

          三、頁面編碼
              頁面編碼主要有兩方面,一是頁面本身的編碼格式,即以什么編碼方式保存,二是客戶端瀏覽器以什么編碼格式顯示頁面。
              1. 頁面保存編碼格式
              1). HTML 頁面的編碼要看你保存文件時的編碼選項,多數的網頁編輯軟件可以讓你選擇編碼的類型,默認為本地編碼,為了使網頁減少編碼的問題,最好保存為 UTF-8 編碼格式。
               2). JSP 頁面使用下列標簽指定 JSP 源文件的編碼格式,具體來說,我們在JSP源文件頭上加入下面的一句即可:
              <%@page pageEncoding="xxx"%>xxx可以為GB2312GBKUTF-8(和MySQL不同,MySQL UTF8)等等,其默認值為ISO-8859-1。保存文件時的編碼應該與xxx 一致。
              2. 頁面顯示編碼(通知客戶端瀏覽器用什么字符集編碼顯示頁面)
             
              使用 <META http-equiv="content-type" content="text/html; charset=xxx"> 標簽設置頁面顯示編碼
              使用 response.setContentType("text/html; charset=xxx");來指定生成的頁面編碼。
             

          使用 <%@ page language="java" contentType="text/html; charset=xxx"%> 設置頁面顯示編碼。字符集的默認值為ISO-8859-1

          3. 頁面輸入編碼

          在設置頁面顯示編碼的同時,指定了頁面的輸入方式。如果沒有指定頁面編碼,則使用操作系統本身的默認編碼。

          四、表單傳遞參數編碼

          使用表單輸入數據時,處理過程如下:

          User input   *(gbk:d6d0 cec4)  

          browser   *(gbk: d6d0 cec4)  

          web server   iso8859-1(00d6 00d 000ce 00c4)   class,需要在class中進行處理:getbytes("iso8859-1")d6 d0 ce c4new String("gbk")d6d0 cec4,內存中以 unicode編碼則為4e2d 6587

          1.用戶輸入的編碼方式和頁面指定的編碼有關。

          2.從 browser web server可以在表單中指定提交內容時使用的字符集,否則會使用頁面指定的編碼。而如果在url中直接用 ? 的方式輸入參數,則其編碼往往是操作系統本身的編碼,因為這時和頁面無關。

          3 Web server接收到的是字節流,默認時(getParameter)會以 iso8859-1編碼處理之,結果是不正確的,所以需要進行處理。但如果預先設置了編碼(通過 request. setCharacterEncoding ()),則能夠直接獲取到正確的結果。

          posted on 2012-08-13 12:23 漂洋過海 閱讀(101) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 宜春市| 定西市| 阿巴嘎旗| 安仁县| 蒲城县| 五指山市| 沂水县| 安顺市| 介休市| 凤台县| 嘉祥县| 汉源县| 南宁市| 龙山县| 竹山县| 南城县| 海宁市| 鄂伦春自治旗| 宜宾市| 安顺市| 开化县| 大埔区| 新平| 保靖县| 迁安市| 新乡市| 闻喜县| 紫金县| 江山市| 普安县| 阿克陶县| 天全县| 天津市| 双柏县| 乐亭县| 河北区| 芮城县| 客服| 阿拉尔市| 额尔古纳市| 大姚县|