构建JAVA应用的国际化
2011年05月25日
我们上国际性的网站,一般都能看到站点的某个地方可以选择对应自己国家的语言环境,从而达到切换语言的功能。
可能很大的一部分都是站点做了镜像或是分布式(判断你的IP地址,之后将你重定向到对应的区域站点)。这种技术还是相当常用的。
不过分布式的坏处就是内容冗余与不同步(两个不同语言站点之间的信息无法同步,内容重复但是又有部分的区别),浪费资源。
所以对于一般的非分布式WEB应用(或者桌面应用)来说,只需要开发单个应用,却拥有语言切换(即国际化)的功能是最好的了。
很幸运,JAVA本身提供了RESOURCEBUNDLE这个类来支持国际化。调用方法为
ResourceBundle rb = ResourceBundle.getBundle("...properties文件名(无扩展名)", locale(区域信息));
但是这个类本身能力有限,它的一个巨大缺点就是,所有的资源束必须放在classpath下面。这对于应用的灵活性是一个巨大的危害。一般的应用肯定预先定义了一个文件夹来统一存放资源束,便于统一维护。
为此,我专门写了一个扩展jar包。这个包很简单。下载地址为:http://u.115.com/file/aq2sofi9
下面简单讲述一下使用方法。
public class Test {
public static void main(String[] arg) throws FileNotFoundException, IOException {
ResourceLoader.loadAll("C:\\strings");
String msg = MessageMgr.getString(resourceName, key, locale);
msg = MessageMgr.getString(resourceName(根据文件夹结构来定义,比如刚才载入的是c盘下的strings文件夹下的所有资源束,在strings文件夹下又有一个文件夹叫com,里面有test.properties与test_zh_CN.properties两个资源文件,那么这个值就是com.test,类似于java中的package), key(资源文件中定义的字段), args(资源替换字段), locale(区域对象));
}
}
主要就是这2条代码了。
下面讲述一下资源束的概念以及如何整合至j2ee应用中。
资源束:顾名思义,就是预定义了一些字串的资源文件。
比如说目前有一个名为test的资源束,那么对应的就是test.properties与test_zh_CN.properties这2个文件了。而在这个资源束中都定义了一个字段键值为MSG_HELLO,于是在test.properties里面有MSG_HELLO=hello,而在test_zh_CN.properties里面就有MSG_HELLO=(你好to UTF-8/转为UTF-8的中文字――你好),注意test之后的_xx_xx就是对应的区域信息,默认是没有的,而中文对应_zh_CN,像美国的话就是_en_US了。想对区域了解更多的可以google搜索下。理论上同一个资源束都是应该放在相同目录下面的。这点切记!
J2EE整合:
拿到这个工具包之后,我们可以在工程的web.xml里面定义一个listener,它的作用就是在应用启动的时候将所有的资源文件全部载入内存当中。(好处就不用我说了吧,内存访问与文件访问,哪个快?)
public class TestListener implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent arg0) {
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
ResourceLoader.loadAll("...");
//在启动环境的时候载入
}
}
由于web应用访问者每个都有一个session,所以将用户选择的区域对象保存至session当中,很简单
Locale locale = new Locale...//用户设定的语言区域信息
session.setAttribute("_locale", locale);
好了,重点来了,某个页面中或是某个请求中需要返回给用户一个多国化的字串,代码就这么写,
Locale locale = session.getAttribute("_locale");
String msg = MessageMgr.getString("com.test", "MSG_HELLO", locale);
之后将这个msg返回给客户端,就达到了多国化的目的
2011年05月25日
我们上国际性的网站,一般都能看到站点的某个地方可以选择对应自己国家的语言环境,从而达到切换语言的功能。
可能很大的一部分都是站点做了镜像或是分布式(判断你的IP地址,之后将你重定向到对应的区域站点)。这种技术还是相当常用的。
不过分布式的坏处就是内容冗余与不同步(两个不同语言站点之间的信息无法同步,内容重复但是又有部分的区别),浪费资源。
所以对于一般的非分布式WEB应用(或者桌面应用)来说,只需要开发单个应用,却拥有语言切换(即国际化)的功能是最好的了。
很幸运,JAVA本身提供了RESOURCEBUNDLE这个类来支持国际化。调用方法为
ResourceBundle rb = ResourceBundle.getBundle("...properties文件名(无扩展名)", locale(区域信息));
但是这个类本身能力有限,它的一个巨大缺点就是,所有的资源束必须放在classpath下面。这对于应用的灵活性是一个巨大的危害。一般的应用肯定预先定义了一个文件夹来统一存放资源束,便于统一维护。
为此,我专门写了一个扩展jar包。这个包很简单。下载地址为:http://u.115.com/file/aq2sofi9
下面简单讲述一下使用方法。
public class Test {
public static void main(String[] arg) throws FileNotFoundException, IOException {
ResourceLoader.loadAll("C:\\strings");
String msg = MessageMgr.getString(resourceName, key, locale);
msg = MessageMgr.getString(resourceName(根据文件夹结构来定义,比如刚才载入的是c盘下的strings文件夹下的所有资源束,在strings文件夹下又有一个文件夹叫com,里面有test.properties与test_zh_CN.properties两个资源文件,那么这个值就是com.test,类似于java中的package), key(资源文件中定义的字段), args(资源替换字段), locale(区域对象));
}
}
主要就是这2条代码了。
下面讲述一下资源束的概念以及如何整合至j2ee应用中。
资源束:顾名思义,就是预定义了一些字串的资源文件。
比如说目前有一个名为test的资源束,那么对应的就是test.properties与test_zh_CN.properties这2个文件了。而在这个资源束中都定义了一个字段键值为MSG_HELLO,于是在test.properties里面有MSG_HELLO=hello,而在test_zh_CN.properties里面就有MSG_HELLO=(你好to UTF-8/转为UTF-8的中文字――你好),注意test之后的_xx_xx就是对应的区域信息,默认是没有的,而中文对应_zh_CN,像美国的话就是_en_US了。想对区域了解更多的可以google搜索下。理论上同一个资源束都是应该放在相同目录下面的。这点切记!
J2EE整合:
拿到这个工具包之后,我们可以在工程的web.xml里面定义一个listener,它的作用就是在应用启动的时候将所有的资源文件全部载入内存当中。(好处就不用我说了吧,内存访问与文件访问,哪个快?)
public class TestListener implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent arg0) {
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
ResourceLoader.loadAll("...");
//在启动环境的时候载入
}
}
由于web应用访问者每个都有一个session,所以将用户选择的区域对象保存至session当中,很简单
Locale locale = new Locale...//用户设定的语言区域信息
session.setAttribute("_locale", locale);
好了,重点来了,某个页面中或是某个请求中需要返回给用户一个多国化的字串,代码就这么写,
Locale locale = session.getAttribute("_locale");
String msg = MessageMgr.getString("com.test", "MSG_HELLO", locale);
之后将这个msg返回给客户端,就达到了多国化的目的