
· 综述
当我们在用JSP设计面对不同国家的站点时,特别是那些在界面之间没有特别大差别的商业站点,我们可以利用JSP的一些机制来支持国际化。
通常有三种方式可以实现国际化
我们重点讨论第三种方法,因为它有很好的灵活性,可维护性和可扩展性。
其实标记库也是利用JAVA的资源捆绑机制, 只是把国际化常用的方法封装的更容易使用,而且更符合JSP的编程思想, 把表述层和逻辑层分开。通用的标记库比较著名的有JAKARTA的I18N标记库。本文包括以下内容:
· JSP国际化的简介
JSP的国际化的基础是JAVA的国际化,都是利用资源捆绑机制把资源与代码分离,通过读取相应的locale信息,自动的匹配相应的资源,并在此基础上实现文本,时间,日期,货币,数字等格式的国际化。关于JAVA国际化的基本概念和方法见 The Java™ Tutorial Internationalization 。
但同一般的JAVA程序的国际化的过程和具体方法还是有很多区别。主要在与locale信息的来源: JSP的locale信息在大部分情况下来自与浏览器,而一般的JAVA程序的locale大都来自当前的JVM。
利用JSP的标记库机制实现国际化:通过使用通用或用户自定义的I18N标记库,可以有很好的灵活性,可维护性和可扩展性。但需要在服务器端配置标记库。
· 如何配置i18n标记库
首先需要一个支持JavaServer Pages Specification 1.1或更高版本的Servlet容器,如Tomcat 4.03,然后按以下步骤配置你的网络服务器。
| <taglib> <taglib-uri>http://jakarta.apache.org/taglibs/i18n-1.0</taglib-uri> <taglib-location>/WEB-INF/i18n.tld</taglib-location> </taglib> |
为了在你的JSP中可以使用它,在每个页面的最顶端加入
| <%@ taglib uri="http://jakarta.apache.org/taglibs/i18n-1.0" prefix="i18n" %> |
其中"i18n"是该标记的前缀,您可以起其他你喜欢的名字。
· i18n标记库的各种标记和使用方法
bundle
为该页的其他I18N标记建立ResourceBundle.如果没有给定locale信息,它会使用浏览器的设定。
注意 :该标记必须写在该页任何HTML标记以前,以便根据所选择的locale信息设置Content Type。
| <%@ taglib uri="http://jakarta.apache.org/taglibs/i18n-1.0" prefix="i18n" %> <i18n:bundle baseName="i18n-test" id="bundle"/> <HTML> <HEAD> ...... |
表1:bundle的属性描述
| 属性名称 | 描述 |
| id | 该ResourceBundle的标识变量, 通过它,其他标记和代码可以访问该ResourceBundle, 当一个页面需要多个ResourceBundle时,可以用它来区分. |
| baseName | ResourceBundle 的基本名,可以连同locale信息定位所需的ResourceBundle. |
| changeResponseLocale | 指定是否改变响应的locale以匹配该标记所用的locale |
| scope | 指定该标记可被访问的范围. (application, session, request, page*) |
| locale | 用户可以指定首选的locale |
| localeAttribute | 不赞成使用 |
| localeRef | 用户可以用属性名指定首选的locale,这个属性名必须在可被访问的范围内 |
| debug | 调试开关 |
*page: 对象被绑定到javax.servlet.jsp.PageContent中,只在该页中可被访问
Request: 对象被绑定到javax.servlet.ServletRequest中,只要HttpRequest对象存在,就可以通过它访问。
Session: 对象被绑定到javax.servlet.jsp.PageContent中,并调用session的getArribute()方法来访问。
Application: 对象被绑定到javax.servlet.ServletContext中,是最持久的范围,所有客户都可以访问到。
Message
从默认或指定的ResourceBundle中读取文本并利用java.text.MessageFormat格式化显示文本
| <i18n:message key="column1.header"/> |
表2:Message的属性描述
| 属性名称 | 描述 |
| id | 该Message的标识变量, 通过它,其他标记和代码可以访问该Message |
| key | 用它得到ResourceBundle中的显示文本 |
| args | 利用数组参数通过java.text.MessageFormat格式化显示文本 |
| bundle | 一个ResourceBundle的参考 |
| bundleRef | 一个代表ResourceBundle的参考的属性名 |
| debug | 调试开关 |
Locale
· 定义LOCALE 信息
JSP国际化和一般的JAVA应用程序国际化的最重要的区别在于Locale信息的源自浏览器, 具体的讲来自request对象.而jakarta的i18n标记库在缺省的情况下可以自动读取request对象中的Locale信息,从而简化了编程和维护的复杂度,当然用户也可以显式的定义Locale信息,解决特殊的显示问题。
表3:Locale的属性描述
| 属性名称 | 描述 |
| id | 该Locale的标识变量, 通过它,其他标记和代码可以访问该Locale |
| locale | 用户可以指定首选的locale |
| localeRef | 用户可以用属性名指定首选的locale,这个属性名必须在可被访问的范围内 |
| language | 用户可以指定首选的语言 |
| country | 用户可以指定首选的国家 |
一个简单的例子:
i18n-test.jsp
| <%@ taglib uri="http://jakarta.apache.org/ taglibs/i18n-1.0" prefix="i18n" %> <i18n:bundle baseName="i18n-test" id="bundle"/> <% java.util.TreeSet set = new java.util.TreeSet(); for ( java.util.Enumeration enum = bundle.getKeys(); enum.hasMoreElements(); ) { set.add(enum.nextElement()); } %> <HTML> <HEAD> <TITLE>Examples of I18N Custom Tag Library Tag Usage</TITLE> </HEAD> <BODY> This page displays all key/value pairs in the bundle. locale = <b><%= pageContext.getResponse(). getLocale() %></b><br> charset = <b><%= pageContext.getResponse(). getCharacterEncoding() %></b><br> <H2>WebApp translations</H2> <TABLE> <% int index = 0; for ( java.util.Iterator iter = set.iterator(); iter.hasNext(); ) { String akey = (String)iter.next(); if ( index++ % 2 == 0 ) { %> <TR BGCOLOR="#e0e0e0"> <% } else { %> <TR> <% } %> <TD><%= akey %></TD><TD>< i18n:message key="<%= akey %>" /><TD> </TR> <% } %> </TABLE> </BODY> </HTML> |
i18n-test.properties
| test1 = Hello world test2 = Now you can let jsp i18n using i18n taglib! |
i18n-test_zh_CN.properties
| test1 = 你好世界 test2 = 现在你可以用i18n标记库国际化JSP了。 |
·
关于作者
翟斌(David Zhai)毕业与北京航空航天大学自动控制专业,学士学位。毕业后一直从事软件开发工作,对网络安全,国际化/本地化有一定的研究。现任职于北京一家开发软件国际化工具的专业公司,从事软件国际化工具的研发。联系方式: zhaibin@yahoo.com