Sunday,2004年June月13日
java webapp i18n處理實踐 要點:為了實現同屏多語言顯示/按照不同用戶locale顯示不同語言,必須全程采用UTF-8編碼。
這幾天筆者剛好在處理roller的i18n,做一下總結。
1, 對properties的處理,必須使用natice2ascii進行編譯;然后采用boudle load. 建議使用jstl進行處理。 例子: <%@ taglib uri="http://java.sun.com/jstl/fmt" prefix="fmt" %>
<fmt:message key="bookmarkForm.correctBookmark" />
2, 對jdbc連接的處理。對于特定的數據庫jdbc driver,需要調整參數。 mysql的例子是: jdbc:mysql://localhost/roller?user=roller&password=roller&autoReconnect=true&useUnicode=true&characterEncoding=utf-8&mysqlEncoding=utf8
3, 對request/response處理,可以采用servlet filter進行設置: public void doFilter( ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { try { // insure that incoming data is parsed as UTF-8 req.setCharacterEncoding("UTF-8"); } catch (UnsupportedEncodingException e) { throw new ServletException("Can't set incoming encoding to UTF-8"); } // keep JSTL and Struts Locale's in synch HttpSession session = ((HttpServletRequest)req).getSession(); if (null != session) { Locale locale = (Locale)session.getAttribute(Globals.LOCALE_KEY); if (locale == null) { locale = req.getLocale(); } if (req.getParameter("locale") != null) { locale = new Locale(req.getParameter("locale")); } session.setAttribute(Globals.LOCALE_KEY, locale); Config.set(session, Config.FMT_LOCALE, locale); } chain.doFilter(req, res); ... }
(這段代碼是從roller的代碼中摘錄的,seasky指出其編寫不夠規范,需要refactor)
4。對每個頁面,在response和頁面中都要指定為utf-8 <%@ page language="java" errorPage="/error.jsp" contentType="text/html; charset=UTF-8" %>
5, 對velocity的處理: in velocity.properties: # set encoding/charset to UTF-8 input.encoding=UTF-8 output.encoding=UTF-8 default.contentType=text/html; charset=utf-8
同時,在java代碼中進行template render時,指定utf-8: VelocityEngine ve = ....; Template outty = getTemplate( "templateName", "UTF-8" );
6, 對Gzip的處理: 其實對Gzip處理沒有什么特殊,記住不要對ByteArrayStream轉換成char[]再進行處理,而是在任何時候都使用byte[]。
下載區中有一個例子。
7, 對regexp的處理。已經有報告說java.util.RegExp處理會導致輸出錯誤。估計也是里面變換的時候用byte[]和char[]倒來倒去出了錯。有條件的請try oro. (我還沒有測試)。
8,對lucene 的修改。 經過測試,lucene 1.3-final不需要任何處理已經可以正確處理中文,GB2312和utf-8都可以。
|