上次的gsp中文編碼問題,我在grails的源碼找到了問題的所在。
grails的gsp servlet程序是通過org.codehaus.groovy.grails.web.pages.GroovyPagesTemplateEngine對gsp進(jìn)行編譯和解釋的,再此過程中同包下的Parse類負(fù)責(zé)了最基本的詞法檢查。但是Parse的readStream(InputStream in)讀取gsp文件時,簡單采用了ByteArrayOutputStream的toString()函數(shù),這個函數(shù)只采用系統(tǒng)默認(rèn)編碼進(jìn)行識別。也就是在這里產(chǎn)生了gsp依賴與操作系統(tǒng)默認(rèn)編碼集的問題。
既然如此,猜測有一個并不完美的解決方法:通過file.encoding系統(tǒng)屬性來指定虛擬機的默認(rèn)編碼集。
比如:grails run-app -Dfile.encoding=GBK
結(jié)果又出乎我的意料,這樣并不能工作,似乎是由于grails本身生成幾個文件是UTF8編碼的,強行指定GBK編碼后會有問題。
看起來,如果你希望部署打包好的war程序包的話,沒有好方法,只能選擇編碼集相同的環(huán)境!
我認(rèn)為好的方法應(yīng)該是grails支持在gsp的servlet配置中增加一個叫做fileEncoding的初始化參數(shù),在讀取文件時應(yīng)用此參數(shù)。這樣大家就可以根據(jù)自己的喜好選擇開發(fā)grails的環(huán)境了。不過目前GroobyPagesServlet類與Parse類之間還隔了GroovyPagesTemplateEngine,并且這個GroovyPagesTemplateEngine的單例初始化是在其他地方完成的,要想實現(xiàn)這個參數(shù)比較繁瑣。
或者要想簡單的話就干脆寫死Parse中使用UTF8,這也是個不錯的選擇,eclipse之類的開發(fā)工具對UTF8的支持很好,其他開發(fā)工具應(yīng)該沒有不支持UTF8的吧。這樣就要求大家都是用UTF8編寫gsp,反正文件中絕大多數(shù)都還是英文字符,也沒多占幾個字節(jié)。
如果上面的方法都不喜歡怎么辦?我還有一個辦法,就是不要在gsp中寫ISO-8859-1字符以外的任何東西,使用i18n輸出你期望的中文字符。其實也就是順帶著把網(wǎng)站所有資源國際化了,呵呵,一舉兩得。不過以我的體驗來說,真要這樣做的話,通常你是會抓狂的,properties文件將超出你想象的瘋長,那個郁悶呀。
而且還要注意,雖然grails說可以配置在發(fā)布時把properties文件自動做native2ascii,但是現(xiàn)有會有類似的問題:原始的properties文件的native編碼是什么?最好還是找個properties的編輯工具,直接保存成ascii的unicode轉(zhuǎn)碼比較好。