這次要討論的問題是過去小弟在開發程式的過程中, 常常碰到的一個問題,小弟把自己解決的經驗加上一些新的 心得整理一下,以供參考。字元編碼的問題在強調跨平台、多語系 的現在,變成一個值得注意的問題,特別對於一些網站形式的 產品來說,總希望不要被侷限於big5的編碼,java在這方面有強大 的彈性,但相對的也有一些需要注意的地方。 我們將問題分成"網頁/應用程式"來作討論。首先, 我們考慮在網頁上的情況:在Sun的forum裡面,透過JSP或是servlet從 表單讀入其他語系的資料算是個蠻熱門的討論,也是很常見的情況,我們就 從這裡為出發點。首先,為了不受地區語系的侷限,我們將網頁作成 UTF-8的編碼。我們在servlet裡面使用下列的方式來讀取表單資料: ============================================================ resp.setContentType("text/html;charset=utf-8"); PrintWriter output=resp.getWriter(); output.println(req.getParameter("name")); output.flush(); ============================================================ 當我們執行這個servlet之後,網頁上出現的會是亂碼!這是因為java不了解 我們將網頁編碼成utf-8,而使用預設的編碼來讀取資料,這時候,只要在 開頭的地方加入一行req.setCharacterEncoding("utf-8"),就可以解決這個問題。 這時問題來了,如果我們改成在jsp中使用下列的寫法,又會出現問題: ============================================================

<% req.setCharacterEncoding("utf-8"); %> <%=request.getParameter("name")%>

============================================================ 如果我們檢查一下從jsp自動產生的java原始碼,就可以發現,當我們對jsp不指定 編碼的時候,compiler會加上一行setContentType("text/html;charset=iso8859-1") ,也就是會設定成為預設的編碼,因此只要在開頭加上一行<%@page contentType="text/html;charset=utf-8"%> 就可以了。當然,這樣子有些不夠漂亮,我們可以使用filter來作處理: ============================================================ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException { request.setCharacterEncoding(encoding); chain.doFilter(request,response); } ============================================================ 然後讓這個filter去過濾我們自己寫的servlet以及一個名為jsp的servlet就可以解決問題了。 可是,又會有另外一個問題跑出來,有時候我們要讀取的字串並不是由虛擬機器或由容器 交給我們的"第一手"字串,舉例來說,如果我們使用struts的表單,這時候應該怎麼辦呢? 由於struts的表單已經轉換成bean的形式,我們沒有機會在讀取之前設定request的encoding, 這時候我們只好從字串本身來作調整: ============================================================ BufferedReader input=new BufferedReader(new InputStreamReader(new StringBufferInputStream(origin),encoding)); String str=""; while(true) { String tempstr=input.readLine(); if(tempstr==null) break; str+=tempstr; } if(str.length()<=0) return null; else return str; ============================================================ 上面這段程式碼的關鍵是在利用InputStreamReader可以設定編碼的特性來作處理。 另外,如果我們是在應用程式中,那通常不可能在HttpRequest和HttpResponse設定encoding,這時候 的解決方法其實更簡單,我們利用Java的Properties物件,將file.encoding這項環境變數設定為 正確的編碼就可以正確的讀入資料了。