星期日, 2月 25, 2007

Java 與 UTF-8 編碼 (二)



在上一個例子裡面,我使用一個 jsp 以及 html 檔案分別作 form submit (JSP 跟 html 的檔案內容都一樣),並且使用一個 servlet 把傳遞的參數顯示在網頁上面。在上面的例子雖然都可以從網頁上得到正確的結果,但是實際內容卻是不一樣的。


第一個例子使用的是單純 html,而且在 html 裡面有加入 meta tag 指定 charset 為 utf-8:



<meta http-equiv=="Content-Type" contentType="text/html; charset=UTF-8">



另外該 html 檔案存檔的時候,我是採用 UTF-8 格式來存檔,當 Browser 瀏覽這個頁面的時候,會以 UTF-8 編碼方式來解析該網頁。當 form submit 到 servlet 的時候,也同樣會以 UTF-8 的方式來傳遞,因此最後印出來的結果正確無誤。

第二個例子變成以 JSP 的方式來呈現。雖然也同樣加入了 meta tag 指定 charset 為 utf-8,也同樣使用 UTF-8 格式存檔,出來的結果雖然正確,但是如果去檢視 output 的 HTML source,會發現其實內容並不是我們要的。(會以 &#D; 的形式出現, D 代表該字元在 Unicode character set 的 decimal codepoint)

這個問題會產生的原因主要是 JSP Default 的編碼方式是 ISO-8859-1,而中文字並沒有辦法直接以 ISO-8859-1 的方式來編碼,因此 browser 直接將非 ISo-8859-1 字元以該字元在 Unicode character set 的 decimal codepoint 傳遞出去。

上面編碼方式會因為 browser 而有些差異,我測試 IE6 跟 Firefox 的部分就有些差異:例如在 Firefox 上面,使用 get 的方式傳遞 name=中文,會以底下的編碼傳遞:

http://localhost:8080/WebTest/EncodingTestServlet?name=%26%2320013%3B%26%2325991%3B&%E9%80%81%E5%87%BA=Submit+Query

但是在 IE 下則是:

http://localhost:8080/WebTest/EncodingTestServlet?name=%26%2320013%3B%26%2325991%3B&%E9%80%81%E5%87%BA=%26%2336865%3B%26%2320986%3B%26%2326597%3B%26%2335426%3B

差別主要是在最後的部分: Submit+Query 是英文字元,Firefox 並沒有使用 Unicode character set decimal codepoint 格式,但是 IE 卻是全部都轉換為 Unicode character set decimal codepoint。不過前面的參數部分,Firefox 跟 IE 都是一樣的。

我上次在這邊卡了一兩個小時,一直找不到原因。因為我已經指定了 meta tag 為 utf-8,但是結果卻不是我要的。最後我發現 JSP 一定得要強制加上:



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



只有單純加上 html content type meata tag 指定 charset 是沒有用的。因為我檢視了 JSP 產生出來的 Java 檔案,發現若缺少 JSP page 去宣告 charset 的話,JSP 實際上是:

response.setContentType("text/html;charset=ISO-8859-1");

若加入 JSP page 宣告 charset 為 UTF-8,JSP 產生的 Java 檔案內容為:

response.setContentType("text/html;charset=utf-8");


沒有留言: