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都可以。
|