精品伊人久久大香线蕉,开心久久婷婷综合中文字幕,杏田冲梨,人妻无码aⅴ不卡中文字幕

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
從漢化到國際化

內容摘要:

Java對輸入輸入首先有一個“字節流”到“字符流”之間的編碼/解碼過程,這個設置是根據系統配置決定的,為什么PHP之類的應用很少有字符集問題而Java有很好的國際化機制,卻經常出現亂碼問題呢?

簡單的舉例:
有一個包含“你好”這2個中文字的文件實際上是4個字節組成的:C4 E3 BA C3
在英文操作系統中缺省的編碼解碼方式是缺省編碼方式是ISO8859,所以直接從文件中讀取的結果是4個的字節,按ISO8859解碼后在程序中操作的是4個Java字符,雖然每個JAVA字符是16位Unicode,但每個字符仍是8位字節的映射\u00C4\u00E3\u00BA\u00C3,因此處理的仍是“英文”。而顯示過程中,是瀏覽器將字節流正確的顯示成了相應的中文。

而一個Java應用在GBK編碼方式的操作系統中,直接從文件中讀取4個的字節后,按GBK方式解碼后是2個16位的Java字符\u4F60\u597D,每個字都是相應Unicode的CJK區塊所對應的中文。

更多的例子請參考:Java的中文處理學習筆記

這也就是為什么在php等應用很少出字符集問題的原因:在服務器端環境缺省一般是英文(ISO8859-1),等于全部處理使用的都是按字節方式處理的。數據輸入輸出過程中編碼方式完全不被改動,因此亂碼問題很少出現。而Java實際上提供了把每個中文直接當成1個“字”而不是2個字節處理的機制,主要的亂碼問題往往是輸入輸出時編碼解碼方式不一致造成的。而且通過Unicode機制,程序除了實現程序界面根據本地化的適應外,甚至程序處理的內容本身的在不同字符集的操作系統中也是可以通用的,比如:在繁體中文操作系統中編輯的內容,在簡體中文操作系統中也能正常的查詢。以下例子可能更說明問題:

  1. JAVA應用的中文問題:如何通過GNU/Linux系統的本地化設置讓JAVA應用支持中文
  2. Java Web應用設計中的中文問題:通過web.xml設置解決URLEncoder.encode()方法和系統缺省編碼方式相關的問題
  3. 以GOOGLE的搜索引擎為例:說明如何將國際化和本地化應用到自己的應用設計中(UniCode inside Localization outsite)

通過GNU/Linux系統的本地化設置讓JAVA應用支持中文

Java 編程技術中漢字問題的分析及解決這篇直到最近還經常被一些網站轉貼的文章中有一個例子說明了很多中國程序員遇到漢字亂碼問題的思路:"GB2312 it"(漢化)

原文如下:
>>>>>>>
......前不久,我的一位技術上的朋友發信給我說,他終于找到了 Java Servlet 中文問題的根源。兩周以來,他一直為 Java Servlet 的中文問題所困擾,因為每面對一個含有中文字符的字符串都必須進行強制轉換才能夠得到正確的結果(這好象是大家公認的唯一的解決辦法)。后來,他確實不想如此繼續安分下去了,因為這樣的事情確實不應該是高級程序員所要做的工作,他就找出 Servlet 解碼的源代碼進行分析,因為他懷疑問題就出在解碼這部分。經過四個小時的奮斗,他終于找到了問題的根源所在。原來他的懷疑是正確的, Servlet 的解碼部分完全沒有考慮雙字節,直接把 %XX 當作一個字符。(原來 Java Soft 也會犯這幺低級的錯誤!)

如果你對這個問題有興趣或者遇到了同樣的煩惱的話,你可以按照他的步驟對 Servlet.jar 進行修改:

找到源代碼 HttpUtils 中的 static private String parseName ,在返回前將 sb(StringBuffer) 復制成 byte bs[] ,然后 return new String(bs,”GB2312”)。作上述修改后就需要自己解碼了:

HashTable form=HttpUtils .parseQueryString(request.getQueryString())或者

form=HttpUtils.parsePostData(……)

千萬別忘了編譯后放到 Servlet.jar 里面。
......
<<<<<<<<<

請問這位“高級”程序員幾個問題:

  1. 如果這是一個商業產品的話,難道客戶需要你Hacking過的Servlet.jar才運行這個應用嗎?
  2. 難道這個產品只能用在中文平臺的GB2312上嗎?如果是日文應用怎么辦,如法Hacking嗎?

也許我錯了,但我的感覺是犯低級錯誤的不是JAVA:

  1. 首先,在Servlet層就不應該考慮中文輸出的問題,因為,在MVC的設計模式中,Servlet主要的角色是Contrallor,所以,在這一層中,數據應該最好還是Unicode形式,在最后讓Jsp或者通過xslt做針對客戶端瀏覽器的輸出時,再需要考慮本地字符集編碼的問題。
  2. 作為一個標準的國際化應用,JAVA應用的缺省編碼方式不應該是在WEB應用這一層設置的,而是JVM根據系統缺省編碼方式根據操作系統的環境設置(locale, 包括字符集,日期格式等本地化環境)改變來實現。

如何設置可以讓GNU/Linux從系統層次就支持中文編碼(讓JVM缺省的file.encoding就按照中文GB2312或者GBK進行編碼解碼)呢?

以上這篇文章發表在2000年年底,當時的GNU/Linux的內核是基于glibc-2.1開發的,而GLIBC2.1對中文的locale支持還有限,因此,在GNU/Linux上不能根據locale的設置將系統缺省的編碼方式變成GB2312,從而改變JVM缺省的編碼方式。關于GNU/Linux對l10n的支持請看:GNU/Linux程序員必讀:中文化與GB18030標準所以在redhat6.x下,無論你怎么設置locale,系統缺省的缺省file.encoding都是ISO_8859_1。

在redhat7.x 系統內核所基于的glibc-2.2.x對l10n有了更完整的支持,所以可以通過設置
LC_ALL=zh_CN.GB2312;export LC_ALL
LANG=zh_CN.GB2312;export LANG
讓系統缺省的編碼方式變成GB2312。JVM會根據系統的缺省編碼方式設置系統的file.encoding屬性。之后,應用中任何字節流到字符流的轉換,JVM都會按照這一系統缺省編碼方式進行轉換。因此在基于glibc-2.2以上的GNU/Linux上是可以通過locale的設置來改變系統缺省的編碼方式,從而改變上層Java應用的缺省編碼、解碼方式的。

locale設置對JVM file.encoding的影響可以我通過做過的一個試驗說明:hello_unicode.html

由此可見:

  1. GNU/Linux是依靠GNU的工具發展起來的:沒有GNU就沒有GNU/Linux。所以GNU/Linux對本地化的支持,也是在核心的glibc-2.2.x對中文locale有了更好的支持以后才逐步發展起來的。
  2. GNU/Linux對國際化的支持遠遠落后于WINDOWS SOLARIS等商業操作系統:2年甚至更多。

通過web.xml設置解決URLEncoder.encode()方法和系統缺省編碼方式相關的問題

在我所理解的范圍內,J2SE 1.3中非常不符合Java的國際化規范的是在使用URLEncoder的時候:
比如在中文WIN98上運行的應用,使用URLEncoder.encode(String s)時:比如“中文”這2個字符直接被Encoding的話結果是"%3F%3F"=>"??"。原因很簡單,“中文”在encode()過程中應該先按GBK編碼方式編碼成4個字節(\u00d6\u00d0\u00ce\u00c4)后再進行URLEncoding才是正確的。這個在J2SE1.4中也修正了。方法encode(String s)已經不鼓勵使用,取而代之的是除了需要進行URLEncoding的字符串外,同時需要指定字符串編碼方式的encode(String s, String enc)。這樣,URLEncoder就可以和系統缺省的編碼方式無關了。

在J2SE1.3下一個WEB應用如果有這個問題可以通過在WEB-INF/web.xml中設置character-encoding來解決:
<web-app character-encoding="your_system_default_file.encoding">
...
</web-app>

比如:產品是在中文WINDOWS98中運行,系統缺省字符集是用GBK,則這個應用的web.xml需要設置成:
<web-app character-encoding="GBK">
...
</web-app>

UniCode inside, Localization outsite

以上2個方法仍然只是讓應用更方便地本地化了,而應用本身并不是真正的國際化應用。設想一下如何設計一個全球的論壇系統:可以讓中文和日文的用戶都可以方便的瀏覽發表呢?在數據中間處理階段應該以那種字符集存儲呢?答案很簡單:UniCode。以前很多文章都有關于如何設計一個國際化界面的介紹,只是應用的本地化界面輸出,但很少提及數據在中間處理過程中如何適應國際化。

輸入和存儲階段就用UniCode方式進行處理和存儲,以方便應用以后的國際化。GOOGLE的設計就是一個非常好的國際化應用榜樣,我以GOOGLE搜索引擎的國際化支持為例說明如何實現國際化應用的設計。

GOOGLE用戶經常有這樣的感覺:

  1. 為什么我第一次去GOOGLE,出現的就是中文的界面?
  2. 為什么在所有網站中查中文:有時候還會匹配到日文網站的結果?比如:就以"google 秘密"這個查詢為例:我們在輸入框輸入"google 秘密"
    http://www.google.com/search?hl=zh-CN&newwindow=1&q=google+%C3%D8%C3%DC&btnG=Google%CB%D1%CB%F7&lr=

首先我將GOOGLE對查詢的處理流程簡單的說明如下:

  1. 客戶端瀏覽器輸入;
  2. 查詢字符串按客戶端系統編碼方式(GBK)轉換成字節流,并URL Encode后傳給GOOGLE;
  3. GOOLGE將輸入的字符串URL Decode后,按照客戶端的系統編碼方式將這個字符串(字節串)解碼成UniCode
  4. 查詢過程,完全是基于UniCode的匹配過程,比如對于“中文”這2個字在簡體繁體中文和日文里都有,因此無論是何種語言的頁面包含這2個字的頁面都能匹配上。
  5. 結果集輸出:將查詢結果集的內容(UNICODE)按客戶端系統編碼方式(GBK)“編碼”成的字節流,返回給瀏覽器

具體說明:

  • GOOGLE如何識別出瀏覽器使用的“界面語言”:GOOGLE獲得這個查詢字符串的同時,一般會根據hl=zh-CN這個參數,知道了客戶端使用的字符集編碼方式,如果用戶第一次訪問:GOOGLE會根據瀏覽器的發送的請求中包含的Accept language: zh_cn這個頭信息來判別,這就是為什么現在很多用戶第一次去GOOGLE的時候它就能自動識別出來的原因。這個參數在之后的查詢和翻頁過程中通過cookie保存,并通過get方式一直傳遞給GOOGLE(因此你也可以使用使用偏好設置界面語言),從而可靠地識別出客戶端的編碼方式。
  • GOOGLE如何查詢:也許從URL上你可以看到:傳過去的“秘密”這個查詢實際上是%C3%D8%C3%DC=>"秘密"這2個字按GBK(WINDOWS客戶端缺省的編碼方式)編碼方式的4個字節然后再URLEncode后的形式(關于中文編碼方式請參考:漢字的編碼方式),GOOGLE將查詢字符串按這個編碼方式解碼并轉成UniCode,然后用這個UniCode編碼方式的字符串進行內部的查詢操作。而任何語言的頁面都是先轉換成UniCode后存儲在GOOGLE的數據索引庫里的。在UniCode中日文和中文寫法一樣的字,用的是同樣的編碼。因此,如果你沒有指定語言過濾的話,日文網頁的結果就首先被命中了;因此,對于中文客戶端的查詢:如果相應字符在UniCode中和繁體,日文映射的字一樣,就可以匹配到相應的日文網頁,繁體中文網頁...,GOOGLE的查詢結果也首先是UniCode的,最后將UniCode結果按照客戶端的編碼方式轉換成字節流,返回到客戶端。

從以上的分析中我們可以看出:UniCode非常漂亮的解決了應用的國際化問題。對于應用前端來說,剩下的工作就是根據本地編碼環境進行本地化的過程了。

  1. 數據從輸入的開始,就全部先轉換成UniCode,然后再進行處理,并按照UniCode方式集中存儲(UniCode inside)
  2. 數據輸出過程中,只是在最后輸出到客戶端的時候,按照客戶端的本地化設置將UniCode數據轉換成本地字符集,并配以相應語言/字符的界面(Localization outside)

如果應用的開發只是滿足于在國內市場自給自足,“漢化”的思路的大量出現是很自然的。但要是把“漢化”比作UCDOS和RichWin的話,那么這種漢化方式遲早要被內核漢化的WIN95淘汰的。畢竟核心級別對國際化的支持才是一個真正簡化前端應用設計、通用的解決方案。Microsoft和Sun等國際化大公司的產品從一開始就是為全球市場設計的,因此對國際化的支持一致非常重視。相比之下國內軟件行業對相應國際標準顯然重視不足,也很少積極地參與相關標準制定。


 

參考文檔:
Java i18n
http://java.sun.com/docs/books/tutorial/i18n/index.html

Linux 國際化本地化和中文化
http://www.linuxforum.net/doc/i18n-new.html

GNU/Linux 程序員必讀:中文化與GB18030標準
http://www.ccidnet.com/tech/os/2001/07/31/58_2811.html

UniCode FAQ
http://www.cl.cam.ac.uk/~mgk25/UniCode.html
http://www.linuxforum.net/books/UTF-8-UniCode.html (中文版)

Java 編程技術中漢字問題的分析及解決
http://www-900.ibm.com/developerWorks/cn/java/java_chinese/index.shtml

漢字的編碼方式:
http://www.unihan.com.cn/cjk/ana17.htm

*注釋:l10n i18n都是縮寫:用的是英文單詞的首尾字母和其間字母個數
l10n: localization 本地化
i18n: internationalization 國際化

本站僅提供存儲服務,所有內容均由用戶發布,如發現有害或侵權內容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
decode和encode
Python內部編碼轉換
關于C#(ASP.net)存取MySQL LongText字段的心得 - yahle的技術...
第四章 python3 語法基礎之字符集編碼格式
Python2.7字符編碼詳解
Python 編碼錯誤的本質原因
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯系客服!

聯系客服

主站蜘蛛池模板: 集安市| 纳雍县| 曲周县| 苗栗县| 南宫市| 灵山县| 天柱县| 襄樊市| 秀山| 怀集县| 宝山区| 额尔古纳市| 高安市| 和平区| 凌云县| 青冈县| 三亚市| 神池县| 大城县| 吉隆县| 沙洋县| 新绛县| 泸水县| 蓬莱市| 海安县| 周口市| 武强县| 黄梅县| 静安区| 都匀市| 甘南县| 潜山县| 灌阳县| 松滋市| 池州市| 乌拉特中旗| 神池县| 贡觉县| 遂宁市| 北海市| 庆安县|