本次對UUZone Refactor中一個大動作就是采用UTF-8編碼,由于種種的歷史原因,uuzone一直采用GBK編碼,現在要把這個編碼轉成為UTF-8的。
本文不打算討論技術, 所以簡單地說明這個工作進展的一個過程:
* 最早的時候,n年前,我們一個項目需要國際化支持,毫無疑問utf-8是最佳的編碼選擇,這時候項目組就遇到了問題: 本地編寫的文件中的中文都是GBK編碼的, 僅僅設置頁面的contentType="text/html; charset=UTF-8", 出來的全是亂碼...當然拿GBK的東西直接要求對方用UTF-8看,一定是亂碼.?
?? 當時如何解決的過程已經無法了解, 但最終采用的方案是:? 用GBK寫文件, 然后采用JDK中的native2ascii工具轉換. 問題解決了, 但結果就是多了轉碼的過程, 轉碼后的jsp文件人不可讀.
* 做uuzone了,? 項目組建議采用GBK編碼, 因為那個轉碼工作太繁瑣了,而且導致文件不可讀, 調試非常麻煩. 于是uuzone就成了GBK的.
?? 由于采用GBK, 遇到了很多相關的問題... 中途至少有2次我"建議"改用UTF-8, 都被評估認為有太多問題而沒有被采納(郁悶的boss啊...)...
* 發現原來不需要轉碼!? 終于處于某些原因, 我需要自己動手來研究一些技術細節, 發現native2ascii轉碼的工作其實并不需要進行. jsp文件可以直接保存為UTF-8編碼, 輸出的結果就是UTF-8的...而現在的elips,editplus, ultraedit, 甚至notepad都能保存和識別utf-8的文件.
* 終于下定決心轉為UTF-8. 既然如此, 就沒有理由拒絕了. 因此本次refactor項目目標之一就是改用UTF-8.? 既然文件打算用utf-8保存, 那么就需要批量轉換工具...幾下search, 好的工具也找到了.
* 轉! ? 有工具, 不到20秒, 6000多個文件就從GBK轉成了UTF-8文件格式...
* 問題來了! 項目中的XML, properties文件是否轉碼呢? 本來計劃轉...但很快發現,這些文件轉掉后, XML,properties文件的讀取都出了不同程度的問題...總之項目將根本無法運行... 原因何在?原來這些UTF-8的文件有一個所謂BOM頭,也就是告訴你這個文件的編碼是什么...不幸的是Java的xml parser, properties文件parser都不認識這個BOM頭!已經有人把這個作為Bug提交給了SUN并被接受, 可是這個bug一直拖了4年,才在去年在Mustang項目(Java 6.0)中解決! 我們顯然不能用了.
* 幸運的是... 我們可以規避這些問題, 我們并不需要把XML, properties文件轉換成UTF-8的, 只要把jsp轉了即可. 雖然一個項目中的文件兩種保存格式,非常不優雅, 但畢竟這能解決問題啊... 轉換完jsp文件,運行項目, 成功! 打開browser...頁面也出來了!
* 幾乎成功了! 是的, 幾乎成功了...然而在計算機的世界里幾乎成功就是不成功. 因為頁面上的樣式神秘地出了輕微的混亂. 經過n十分鐘仔細研究討論, 終于發現產生的html頁面內出現了幾個神秘的不可見字符... 就是這些可怕的不可見字符, 破壞了頁面的結構.
* 神秘的隱身字符? 和計算機打交道和比人打交道強的一個地方就是在于 -- 如果計算機錯了,一定是你錯了, 因為計算機一定忠實執行你的指令. 神秘的不可見字符一定有其來歷. 經過二進制分析, 找到了這些神秘字符出現的地方 ---jsp include! 每次include就會出現神秘字符, 而這些神秘字符的值也是老朋友了 -- 就是BOM header !?
* 難道不能include了?? 原來java顯然和xml文件一樣對待了這些BOM頭, 這些FF FE之類的東西成了輸出的一部分. google 去查, 看到一個人顯然遇到完全相同的問題, 可惜是個俄羅斯的程序員, 也看不懂其文章... :(
??? 怎么辦?? 有同學說: 既然你要UTF-8 (心想: 誰讓你是boss呢? 愚蠢的boss啊...:-) ) , 我們還是用native2ascii吧...? 不行!?
* 遇到困難要思考. 思考...
??? 首先, 為什么java文件不需要轉碼(java 文件中的中文無論如何都能正確)? 為什么jsp要? jsp不是被預編譯成java的嗎??
??? 從那個sun承認的bug, 顯然可以得出一個結論, java虛擬機中的file input stream沒有能自動很具BOM識別文件編碼.?
??? 也許javac是比較native的代碼, 能通過操作系統獲得native編碼類型, 而java內部是unicode的, 所以輸出也同樣沒問題.? 而jsp是動態編譯的, 預編譯器是JVM...其待遇顯然和xml等是一樣的...
?? 難道sun公司的人會愚蠢到這種地步? 不可能, 一定是我們愚蠢.繼續google 學習...
??? 不幸的是大部分google上關于這類編碼問題的討論都是不完整的. 但一個神秘的pageEncoding跳進了眼簾, 已經指定了contentType的encoding, 為什么還要指定pageEncoding?? 查一下jsp的資料, 顯然這正是問題所在!? pageEncoding就是告訴JVM 這個jsp本身采用的encoding, 默認采用iso-8859. 我們明明用GBK的native編碼, 讓JVM拿iso8859讀取,當然不對了!!
* 根本沒有需要轉碼, 問題解決了! 是的, 明白了原因所在, 把所有jsp文件頭修改為: <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="GBK" %> 不需要任何轉碼,最終輸出的就是UTF-8, 沒有任何問題. 而且這些文件采用native格式保存, 編輯最方便!
posted on 2006-05-28 01:08
老妖 閱讀(2008)
評論(2) 編輯 收藏