免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
從漢化到國(guó)際化

內(nèi)容摘要:

Java對(duì)輸入輸入首先有一個(gè)“字節(jié)流”到“字符流”之間的編碼/解碼過(guò)程,這個(gè)設(shè)置是根據(jù)系統(tǒng)配置決定的,為什么PHP之類(lèi)的應(yīng)用很少有字符集問(wèn)題而Java有很好的國(guó)際化機(jī)制,卻經(jīng)常出現(xiàn)亂碼問(wèn)題呢?

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

而一個(gè)Java應(yīng)用在GBK編碼方式的操作系統(tǒng)中,直接從文件中讀取4個(gè)的字節(jié)后,按GBK方式解碼后是2個(gè)16位的Java字符\u4F60\u597D,每個(gè)字都是相應(yīng)Unicode的CJK區(qū)塊所對(duì)應(yīng)的中文。

更多的例子請(qǐng)參考:Java的中文處理學(xué)習(xí)筆記

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

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

通過(guò)GNU/Linux系統(tǒng)的本地化設(shè)置讓JAVA應(yīng)用支持中文

Java 編程技術(shù)中漢字問(wèn)題的分析及解決這篇直到最近還經(jīng)常被一些網(wǎng)站轉(zhuǎn)貼的文章中有一個(gè)例子說(shuō)明了很多中國(guó)程序員遇到漢字亂碼問(wèn)題的思路:"GB2312 it"(漢化)

原文如下:
>>>>>>>
......前不久,我的一位技術(shù)上的朋友發(fā)信給我說(shuō),他終于找到了 Java Servlet 中文問(wèn)題的根源。兩周以來(lái),他一直為 Java Servlet 的中文問(wèn)題所困擾,因?yàn)槊棵鎸?duì)一個(gè)含有中文字符的字符串都必須進(jìn)行強(qiáng)制轉(zhuǎn)換才能夠得到正確的結(jié)果(這好象是大家公認(rèn)的唯一的解決辦法)。后來(lái),他確實(shí)不想如此繼續(xù)安分下去了,因?yàn)檫@樣的事情確實(shí)不應(yīng)該是高級(jí)程序員所要做的工作,他就找出 Servlet 解碼的源代碼進(jìn)行分析,因?yàn)樗麘岩蓡?wèn)題就出在解碼這部分。經(jīng)過(guò)四個(gè)小時(shí)的奮斗,他終于找到了問(wèn)題的根源所在。原來(lái)他的懷疑是正確的, Servlet 的解碼部分完全沒(méi)有考慮雙字節(jié),直接把 %XX 當(dāng)作一個(gè)字符。(原來(lái) Java Soft 也會(huì)犯這幺低級(jí)的錯(cuò)誤?。?/i>

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

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

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

form=HttpUtils.parsePostData(……)

千萬(wàn)別忘了編譯后放到 Servlet.jar 里面。
......
<<<<<<<<<

請(qǐng)問(wèn)這位“高級(jí)”程序員幾個(gè)問(wèn)題:

  1. 如果這是一個(gè)商業(yè)產(chǎn)品的話,難道客戶(hù)需要你Hacking過(guò)的Servlet.jar才運(yùn)行這個(gè)應(yīng)用嗎?
  2. 難道這個(gè)產(chǎn)品只能用在中文平臺(tái)的GB2312上嗎?如果是日文應(yīng)用怎么辦,如法Hacking嗎?

也許我錯(cuò)了,但我的感覺(jué)是犯低級(jí)錯(cuò)誤的不是JAVA:

  1. 首先,在Servlet層就不應(yīng)該考慮中文輸出的問(wèn)題,因?yàn)?,在MVC的設(shè)計(jì)模式中,Servlet主要的角色是Contrallor,所以,在這一層中,數(shù)據(jù)應(yīng)該最好還是Unicode形式,在最后讓Jsp或者通過(guò)xslt做針對(duì)客戶(hù)端瀏覽器的輸出時(shí),再需要考慮本地字符集編碼的問(wèn)題。
  2. 作為一個(gè)標(biāo)準(zhǔn)的國(guó)際化應(yīng)用,JAVA應(yīng)用的缺省編碼方式不應(yīng)該是在WEB應(yīng)用這一層設(shè)置的,而是JVM根據(jù)系統(tǒng)缺省編碼方式根據(jù)操作系統(tǒng)的環(huán)境設(shè)置(locale, 包括字符集,日期格式等本地化環(huán)境)改變來(lái)實(shí)現(xiàn)。

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

以上這篇文章發(fā)表在2000年年底,當(dāng)時(shí)的GNU/Linux的內(nèi)核是基于glibc-2.1開(kāi)發(fā)的,而GLIBC2.1對(duì)中文的locale支持還有限,因此,在GNU/Linux上不能根據(jù)locale的設(shè)置將系統(tǒng)缺省的編碼方式變成GB2312,從而改變JVM缺省的編碼方式。關(guān)于GNU/Linux對(duì)l10n的支持請(qǐng)看:GNU/Linux程序員必讀:中文化與GB18030標(biāo)準(zhǔn)。所以在redhat6.x下,無(wú)論你怎么設(shè)置locale,系統(tǒng)缺省的缺省file.encoding都是ISO_8859_1。

在redhat7.x 系統(tǒng)內(nèi)核所基于的glibc-2.2.x對(duì)l10n有了更完整的支持,所以可以通過(guò)設(shè)置
LC_ALL=zh_CN.GB2312;export LC_ALL
LANG=zh_CN.GB2312;export LANG
讓系統(tǒng)缺省的編碼方式變成GB2312。JVM會(huì)根據(jù)系統(tǒng)的缺省編碼方式設(shè)置系統(tǒng)的file.encoding屬性。之后,應(yīng)用中任何字節(jié)流到字符流的轉(zhuǎn)換,JVM都會(huì)按照這一系統(tǒng)缺省編碼方式進(jìn)行轉(zhuǎn)換。因此在基于glibc-2.2以上的GNU/Linux上是可以通過(guò)locale的設(shè)置來(lái)改變系統(tǒng)缺省的編碼方式,從而改變上層Java應(yīng)用的缺省編碼、解碼方式的。

locale設(shè)置對(duì)JVM file.encoding的影響可以我通過(guò)做過(guò)的一個(gè)試驗(yàn)說(shuō)明:hello_unicode.html

由此可見(jiàn):

  1. GNU/Linux是依靠GNU的工具發(fā)展起來(lái)的:沒(méi)有GNU就沒(méi)有GNU/Linux。所以GNU/Linux對(duì)本地化的支持,也是在核心的glibc-2.2.x對(duì)中文locale有了更好的支持以后才逐步發(fā)展起來(lái)的。
  2. GNU/Linux對(duì)國(guó)際化的支持遠(yuǎn)遠(yuǎn)落后于WINDOWS SOLARIS等商業(yè)操作系統(tǒng):2年甚至更多。

通過(guò)web.xml設(shè)置解決URLEncoder.encode()方法和系統(tǒng)缺省編碼方式相關(guān)的問(wèn)題

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

在J2SE1.3下一個(gè)WEB應(yīng)用如果有這個(gè)問(wèn)題可以通過(guò)在WEB-INF/web.xml中設(shè)置character-encoding來(lái)解決:
<web-app character-encoding="your_system_default_file.encoding">
...
</web-app>

比如:產(chǎn)品是在中文WINDOWS98中運(yùn)行,系統(tǒng)缺省字符集是用GBK,則這個(gè)應(yīng)用的web.xml需要設(shè)置成:
<web-app character-encoding="GBK">
...
</web-app>

UniCode inside, Localization outsite

以上2個(gè)方法仍然只是讓?xiě)?yīng)用更方便地本地化了,而應(yīng)用本身并不是真正的國(guó)際化應(yīng)用。設(shè)想一下如何設(shè)計(jì)一個(gè)全球的論壇系統(tǒng):可以讓中文和日文的用戶(hù)都可以方便的瀏覽發(fā)表呢?在數(shù)據(jù)中間處理階段應(yīng)該以那種字符集存儲(chǔ)呢?答案很簡(jiǎn)單:UniCode。以前很多文章都有關(guān)于如何設(shè)計(jì)一個(gè)國(guó)際化界面的介紹,只是應(yīng)用的本地化界面輸出,但很少提及數(shù)據(jù)在中間處理過(guò)程中如何適應(yīng)國(guó)際化。

輸入和存儲(chǔ)階段就用UniCode方式進(jìn)行處理和存儲(chǔ),以方便應(yīng)用以后的國(guó)際化。GOOGLE的設(shè)計(jì)就是一個(gè)非常好的國(guó)際化應(yīng)用榜樣,我以GOOGLE搜索引擎的國(guó)際化支持為例說(shuō)明如何實(shí)現(xiàn)國(guó)際化應(yīng)用的設(shè)計(jì)。

GOOGLE用戶(hù)經(jīng)常有這樣的感覺(jué):

  1. 為什么我第一次去GOOGLE,出現(xiàn)的就是中文的界面?
  2. 為什么在所有網(wǎng)站中查中文:有時(shí)候還會(huì)匹配到日文網(wǎng)站的結(jié)果?比如:就以"google 秘密"這個(gè)查詢(xún)?yōu)槔何覀冊(cè)谳斎肟蜉斎?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對(duì)查詢(xún)的處理流程簡(jiǎn)單的說(shuō)明如下:

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

具體說(shuō)明:

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

從以上的分析中我們可以看出:UniCode非常漂亮的解決了應(yīng)用的國(guó)際化問(wèn)題。對(duì)于應(yīng)用前端來(lái)說(shuō),剩下的工作就是根據(jù)本地編碼環(huán)境進(jìn)行本地化的過(guò)程了。

  1. 數(shù)據(jù)從輸入的開(kāi)始,就全部先轉(zhuǎn)換成UniCode,然后再進(jìn)行處理,并按照UniCode方式集中存儲(chǔ)(UniCode inside)
  2. 數(shù)據(jù)輸出過(guò)程中,只是在最后輸出到客戶(hù)端的時(shí)候,按照客戶(hù)端的本地化設(shè)置將UniCode數(shù)據(jù)轉(zhuǎn)換成本地字符集,并配以相應(yīng)語(yǔ)言/字符的界面(Localization outside)

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


 

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

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

GNU/Linux 程序員必讀:中文化與GB18030標(biāo)準(zhǔn)
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 編程技術(shù)中漢字問(wèn)題的分析及解決
http://www-900.ibm.com/developerWorks/cn/java/java_chinese/index.shtml

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

*注釋?zhuān)簂10n i18n都是縮寫(xiě):用的是英文單詞的首尾字母和其間字母?jìng)€(gè)數(shù)
l10n: localization 本地化
i18n: internationalization 國(guó)際化

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服