i18n

概述

tio-boot 为国际化提供了极速化的支持,国际化模块仅三个类文件,使用方式要比 spring 这类框架容易得多。

I18n 与 Res

I18n 对象可通过资源文件的 baseName 与 locale 参数获取到与之相对应的 Res 对象,Res 对象提供了 API 用来获取国际化数据。

以下给出具体使用步骤:

  • 创建 i18n_en_US.properties、i18n_zh_CN.properties 资源文件,i18n 即为资源文件的 baseName,可以是任意名称,在此示例中使用”i18n”作为 baseName

  • i18n_en_US.properties 文件中添加如下内容

msg=Hello {0}, today is{1}.
  • i18n_zh_CN.properties 文件中添加如下内容
msg=你好{0}, 今天是{1}.
  • 你可以子项目启动时使用 I18n.setDefaultBaseName("i18n")配置资源文件默认 baseName

特别注意,java 国际化规范要求 properties 文件的编辑需要使用专用的编辑器,否则会出乱码,如果使用 Eclipse 进行开发,推荐安装 Kantan Properties Editor

以下是基于以上步骤以后的代码示例:

// 通过locale参数en_US得到对应的Res对象
Res resEn = I18n.use("en_US");
// 直接获取数据
String msgEn = resEn.get("msg");
// 获取数据并使用参数格式化
String msgEnFormat = resEn.format("msg", "james", new Date());

// 通过locale参数zh_CN得到对应的Res对象
Res resZh = I18n.use("zh_CN");
// 直接获取数据
String msgZh = resZh.get("msg");
// 获取数据并使用参数格式化
String msgZhFormat = resZh.format("msg", "詹波", new Date());

// 另外,I18n还可以加载未使用me.setI18nDefaultBaseName()配置过的资源文件,唯一的不同是
// 需要指定baseName参数,下面例子需要先创建otherRes_en_US.properties文件
Res otherRes = I18n.use("otherRes", "en_US");
otherRes.get("msg");

I18nInterceptor

I18nInterceptor 拦截器是针对于 web 应用提供的一个国际化组件,以下是在 freemarker 模板中使用的例子:

//先将I18nInterceptor配置成全局拦截器
public void configInterceptor(Interceptors me) {
  me.add(new I18nInterceptor());
}


// 然后在 jfinal 模板引擎中即可通过 _res 对象来获取国际化数据
#(_res.get("msg"))

以上代码通过配置了 I18nInterceptor 拦截 action 请求,然后即可在 freemarker 模板文件中通过名为_res 对象来获取国际化数据,I18nInterceptor 的具体工作流程如下:

试图从请求中通过 request.getParam(“_locale”)获取 locale 参数,如果获取到则将其保存到 cookie 之中

如果 request.getParam(“_locale”)没有获取到参数值,则试图通过 request.getCookie(“_locale”)得到 locale 参数

如果以上两步仍然没有获取到 locale 参数值,则使用 I18n. defaultLocale 的值做为 locale 值来使用

使用前面三步中得到的 locale 值,通过 I18n.use(locale)得到 Res 对象,并通过 request.setAttribute(“_res”, res)将 Res 对象传递给页面使用

如果 I18nInterceptor. isSwitchView 为 true 值的话还会改变 render 的 view 值,实现整体模板文件的切换,详情可查看源码。

以上步骤 I18nInterceptor 中的变量名”_locale”、”_res”都可以在创建 I18nInterceptor 对象时进行指定,不指定时将使用默认值。还可以通过继承 I18nInterceptor 并且覆盖 getLocalPara、getResName、getBaseName 来定制更加个性化的功能。

在有些 web 系统中,页面需要国际化的文本过多,并且 css 以及 html 也因为国际化而大不相同,对于这种应用场景先直接制做多套同名称的国际化视图,并将这些视图以 locale 为子目录分类存放,最后使用 I18nInterceptor 拦截器根据 locale 动态切换视图,而不必对视图中的文本逐个进行国际化切换,只需将 I18nInterceptor.isSwitchView 设置为 true 即可,省时省力。

I18nLocale

方便开发,TioBoot 内置了 I18nLocale 类

com.litongjava.tio.boot.i18n.I18nLocale