love fish大鵬一曰同風(fēng)起,扶搖直上九萬里

          常用鏈接

          統(tǒng)計(jì)

          積分與排名

          friends

          link

          最新評論

          編碼問題(轉(zhuǎn))

          今天看了子華的博客中關(guān)于昨晚我們討論編碼方面的問題,發(fā)現(xiàn)其中有一個(gè)關(guān)鍵點(diǎn)沒有談到。
          ??? 情況是這樣的:我們現(xiàn)在使用的一個(gè)名為Notepad++的編輯器,它大體上和UltraEdit類似,是我從sourceforge上下載下載使用的。它有個(gè)格式的功能,簡單而言就是設(shè)置使用ascii編碼編輯文檔還是使用utf-8編碼,其實(shí)這里主要是對應(yīng)非英文方面的字符才發(fā)生差異。
          ??? 如前那篇隨筆所述utf-8只是用于在數(shù)據(jù)傳輸時(shí)將字符串分割成字節(jié)傳輸出去,它對于unicode編碼有著嚴(yán)格的一一對應(yīng)關(guān)系,而對于gb2312、gbk、gb18030之類的中文編碼是沒有對應(yīng)關(guān)系的。gb2312、gbk、gb18030是在ascii編碼之上進(jìn)行的中文編碼開發(fā),所以它們是與ascii相兼容的,可以這么理解在我們的文本編輯器中ascii方式編輯的文本是以ascii碼保存,而以utf-8方式編輯的文本是以unicode編碼保存。
          ??? 現(xiàn)在,編碼的差異就在這里發(fā)生了,unicode中的英文部分編碼是與ascii相兼容的,具體而言是iso8859-1兼容,所以我們無論用什么編碼保存方式保存jsp文件,在網(wǎng)頁上顯示的都是正確的英文字符。但是對于中文這個(gè)保存的格式卻非常重要。在了解了jsp頁面的顯示過程我們就會明白其中的原因。
          ??? 現(xiàn)在回頭來看看jsp文件是經(jīng)過了哪些步驟才在網(wǎng)頁上顯示出來的。
          ??? 1、首先我們用編輯器編輯jsp頁面代碼保存;
          ??? 2、web服務(wù)器對其進(jìn)行編譯,將jsp頁面編譯成為一個(gè)java的class文件;
          ??? 3、web服務(wù)器將其class文件用傳輸格式在網(wǎng)絡(luò)上傳輸;
          ??? 4、客戶端瀏覽器解析代碼生成頁面。
          ??? 過程大致如上,能夠影響編碼方面的基本上在1、2、4方面,所以對其進(jìn)行詳細(xì)講解。
          ??? 我們的編輯器是有一種默認(rèn)的編碼保存方式的。這會到后面java編譯器是否將其中的中文進(jìn)行轉(zhuǎn)換的問題。大家都知道java是以十六位的unicode編碼編譯、存儲java文件的。因?yàn)橥粋€(gè)漢字在unicode編碼和gb2312編碼中的位置是不一樣的,(具體而言就是這兩種編碼沒有兼容性,也不能通過公式換算出來,只能通過字符對應(yīng)表進(jìn)行轉(zhuǎn)換)
          ??? 上面指出的保存格式的重要性就在這里體現(xiàn)出來了,這也是很多人容易遺漏之處,當(dāng)我們用默認(rèn)格式位gbk的編輯器編輯jsp頁面,而在其頭部聲明charset=utf-8,那么返回的頁面會出現(xiàn)亂碼,而charset=gb2312則正常顯示。本人分析原因在于,在charset=utf-8的聲明有誤時(shí),java編譯器會錯(cuò)誤的認(rèn)為現(xiàn)在保存的文件就是以unicode編碼格式保存的文件,所以在編譯中就不對其中的中文字符進(jìn)行g(shù)b2312--unicode的轉(zhuǎn)化,而直接將其gb2312指向的編碼地址保存為unicode的編碼地址。反之,當(dāng)編輯器的默認(rèn)編輯保存格式為utf-8時(shí),在jsp中聲明為gb2312,就會讓編譯器畫蛇添足的多進(jìn)行一次中文編碼轉(zhuǎn)換,從而亂碼出現(xiàn)。
          ??? 綜上所述,編輯器的默認(rèn)編碼方式是在解決中文亂碼方面是很重要的一個(gè)因素,當(dāng)然我們可以用pageEncoding參數(shù)來說明文本編碼形式。弄清中文顯示后面的具體調(diào)用過程是徹底解決該類問題的終極之道!

          posted on 2006-12-07 14:42 stme 閱讀(490) 評論(7) ?編輯?收藏引用收藏至365Key

          評論

          #?re: 編碼問題 2006-12-07 16:22 BeanSoft

          不錯(cuò), 必須在頭部加入下列聲明:

          <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="GBK"%>

          要不然你就得用編輯器另存為的時(shí)候(例如記事本就有這個(gè)功能, 但是貌似有問題)轉(zhuǎn)換編碼為 UTF-8.

          服務(wù)器看到 contentType="text/html; charset=UTF-8" 的頁面聲明的時(shí)候, 就認(rèn)為下面的內(nèi)容都是 UTF-8, 如果這時(shí)候不加上 pageEncoding, 出來的內(nèi)容自然就是亂碼.

          因此要么都用 GBK, 要么都用 UTF-8. 可以在 Eclipse 里進(jìn)行設(shè)置讓所有的源文件的默認(rèn)字符集都是 UTF-8. 如果要做開源項(xiàng)目, 強(qiáng)烈建議的是不要用 GBK 格式的編碼, 用 UTF-8 是上上策. 還有就是鼓勵(lì)英文注釋, 網(wǎng)頁內(nèi)容國際化, 呵呵.??回復(fù)??

          #?re: 編碼問題 2006-12-07 17:00 hahahehe

          1、首先我們用編輯器編輯jsp頁面代碼保存;
          2、web服務(wù)器對其進(jìn)行編譯,將jsp頁面編譯成為一個(gè)java的class文件;
          3、web服務(wù)器將其class文件用傳輸格式在網(wǎng)絡(luò)上傳輸;
          4、客戶端瀏覽器解析代碼生成頁面。

          非applet的情況下,服務(wù)器怎么可能把class傳輸?shù)骄W(wǎng)絡(luò)上去,瀏覽器又怎么可能解析class?服務(wù)器傳輸?shù)氖莌tml,class生成html的過程早在服務(wù)器端就已經(jīng)完成。

          亂碼的直接原因就在于服務(wù)器在頭里告訴瀏覽器的編碼 charset=UTF-8 和事實(shí)上生成html的編碼是不一致的??回復(fù)??

          #?re: 編碼問題 2006-12-07 17:13 BeanSoft[匿名]

          呵呵, 這段話的確是有點(diǎn)問題...

          應(yīng)該是:
          1. 我們用代碼編輯器編輯了一個(gè)頁面(encoding=GBK)
          2. Web 服務(wù)器調(diào)用編譯器將其編譯為 servlet(編譯器也會有個(gè) encoding 選項(xiàng), 一般都是跟著系統(tǒng)的 encoding 走, 頁面有 charset 的話就跟頁面的 charset 或者 pageEncoding 一致, 所以有時(shí)候不指定JSP編譯默認(rèn)編碼, 不同的服務(wù)器出來的結(jié)果就不一樣), (encoding=GBK);
          3. 生成 HTML, 這沒啥, 直接 write string;
          4. 瀏覽器根據(jù) head 里的 contentType (UTF-8)來判斷編碼, 或者根據(jù)頁面里的 meta 來判斷編碼
          <meta http-equiv="content-type" content="text/html; charset=UTF-8">, 什么都沒的時(shí)候就當(dāng)成西歐字符集, 具體哪個(gè)優(yōu)先? 印象中是頁面里的 meta 優(yōu)先, 這時(shí)候客戶需要手工選一個(gè)編碼才能看到正確的網(wǎng)頁.

          所以只有這些條件都一致的時(shí)候, 才不會亂碼, 否則都會亂碼. 一般推薦全用 UTF-8(英文服務(wù)器環(huán)境) 或者 GBK(中文服務(wù)器).??回復(fù)??

          #?re: 編碼問題 2006-12-08 00:27 weidagang2046

          上次看你另一篇文章,對編碼分析得很詳細(xì),很有幫助。再接再厲!??回復(fù)??

          #?re: 編碼問題 2006-12-08 09:44 stme[匿名]

          謝謝大家的點(diǎn)評,大家一起進(jìn)步吧!??回復(fù)??

          #?re: 編碼問題 2006-12-08 13:44 laoshi

          >>utf-8只是用于在數(shù)據(jù)傳輸時(shí)將字符串分割成字節(jié)傳輸出去,它對于unicode編碼有著嚴(yán)格的一一對應(yīng)關(guān)系,而對于gb2312、gbk、gb18030之類的中文編碼是沒有對應(yīng)關(guān)系的。gb2312、gbk、gb18030是在ascii編碼之上進(jìn)行的中文編碼開發(fā),所以它們是與ascii相兼容的
          gb18030也和unicode有著嚴(yán)格的一一對應(yīng)關(guān)系,gb2312、gbk和unicode的子集有著嚴(yán)格的一一對應(yīng)關(guān)系
          UTF-8和gb18030都是所謂的外碼標(biāo)準(zhǔn)
          “gb2312、gbk、gb18030是在ascii編碼之上進(jìn)行的中文編碼開發(fā),所以它們是與ascii相兼容的”是錯(cuò)誤的,只能說UTF-8以及國標(biāo)編碼的單字節(jié)編碼區(qū)和ascii的0~7F區(qū)的編碼是一致的。
          Notepad++和UltraEdit的ascii其實(shí)并不是ascii,而是指Windows平臺的本地多字節(jié)字符集,一般咱們用的中文Windows上就是gbk??回復(fù)??

          #?re: 編碼問題2006-12-08 16:13 luguoren

          ”gb18030也和unicode有著嚴(yán)格的一一對應(yīng)關(guān)系,gb2312、gbk和unicode的子集有著嚴(yán)格的一一對應(yīng)關(guān)系“
          這個(gè)是對的嗎?本人好像沒有看到這樣的資料,gb18030只是一部分與unicode對應(yīng),不會是全部一一對應(yīng)吧??回復(fù)??

          posted on 2006-12-10 11:46 liaojiyong 閱讀(432) 評論(0)  編輯  收藏 所屬分類: JSP

          主站蜘蛛池模板: 鹤峰县| 东至县| 丰都县| 肇源县| 如东县| 紫阳县| 仁寿县| 铁力市| 偃师市| 屏东市| 东台市| 龙山县| 彭水| 怀来县| 原阳县| 尖扎县| 家居| 内丘县| 台南市| 专栏| 曲松县| 广水市| 六盘水市| 从江县| 邵阳市| 泉州市| 海伦市| 区。| 万盛区| 盐城市| 三原县| 阿拉善右旗| 屯留县| 英德市| 繁峙县| 九龙县| 南京市| 荣昌县| 塘沽区| 临猗县| 建宁县|