本地化字符串

Jul 10, 2017 10:38:44 AM

作者:zozoh

基本策略

每个 Mvc 框架都有自己的本地化字符串的解决方案, Nutz.Mvc 的这个是相当简陋的。我只是个人觉得足够用了。下面我把它简单介绍一下:

  • 假定所有的本地化字符串文件都会存放在某一目录
    • 这个目录下所有的 .properties 文件,将作为默认的本地字符串文件。
    • 每一种语言都会是一个目录,目录名称对应一个 Locale 的 toString(),请参看 java.util.Locale 的 JDoc
      • 比如简体中文,就是 zh_CN
      • 比如美式英语,就是 en_US
    • 目录下所有的 .properties 文件存放着该地区的字符串信息
    • .properties 文件需要按照 UTF-8 方式编码
  • 目录,通过 @Localization("路径/") 声明在主模块上
  • 当应用启动时,一次读入所有的字符串,并存入 ServletContext,属性名称为:“org.nutz.mvc.annotation.Localization”
  • 应用可以自行设置当前 Session 是哪一个国家和地区
    • Mvcs.setLocaleName(String localeName)
  • 每次请求时,会根据 Session 中的 localeName,从 ServletContext 中将对应 Locale 的字符串取出,设入 Request 对象
    • 属性名为 "msg",无论@Localization声明的路径是什么,在页面(JSP/JSTL/其他模板引擎)中, 它的名字都不会变化.
    • 如果当前会话没有被设置 Locale,则将 "msg" 设置成默认本地化字符串

使用字符串

目录结构, 以maven为例

  1. - src
  2. - main
  3. - resources
  4. - msgs
  5. - zh_CN
  6. user.properties
  7. role.properties
  8. - en_US
  9. user.properties
  10. role.properties

在主模块上声明

比如:

  1. ...
  2. @Localization("msgs/") // 注意是文件夹的名字
  3. public class MainModule {
  4. ...
  • 在主模块上声明 @Localization 注解,指向一个目录
  • 在目录下建立文件夹,比如 zh_CN,每个目录下所有 .properties 文件都会被当作字符串文件
  • .properties 文件 一定要是 UTF-8 编码的
  • 比如 @Locallization("msgs/") 会指向 CLASSPATH 下的 msgs/ 目录

在 JSP 里使用

直接 Scriptlet

  1. ...
  2. <h1><%=((Map<String,String>)request.getAttribute("msg")).get("my.msg.key")%></h1>
  3. ...

采用 JSTL

  1. ...
  2. <h1>${msg['my.msg.key']}</h1>
  3. ...

我到底支持哪些语言

请参看 org.nutz.mvc.Mvcs 的 JavaDoc,这里我列几个常用的方法:

Mvcs.getLocalizationKey() 获取当前会话的 Locale 名称
Mvcs.setLocalizationKey(String key) 为当前会话设置 Locale 的名称
Mvcs.getLocalizationKeySet() 获取整个应用可用的 Locale 名称集合

切换本地语言

  1. // 设置一个本地字符串
  2. @At("/lang/change")
  3. @Ok("redirect:/")
  4. public void changeLocal( @Param("lang") String lang){
  5. Mvcs.setLocalizationKey(lang);
  6. }

设置应用程序的默认语言

  1. ...
  2. @Localization(value="mymsg/", defaultLocalizationKey="zh_CN")
  3. public class MainModule {
  4. ...

定制自己的本地化字符串方式

你需要自己实现一个 MessageLoader 的接口,然后声明到 '@Localization' 中。比如你的实现类名字为 'MyMessageLoader',那么你应该这么声明:

  1. ...
  2. @Localization( type=MyMessageLoader.class,
  3. value="msg" )
  4. public class MainModule {
  5. ...

对于 MessageLoader 接口,就一个方法需要你来实现:

  1. public interface MessageLoader {
  2. /**
  3. * 本函数将根据传入的 "refer" 参数,返回一个 Map <br>
  4. * Map 的键是语言的名称,比如 "en_US", "zh_CN" 等,<br>
  5. * 你会通过 Mvcs.setLocalizationKey 来直接使用这个键值
  6. * <p>
  7. * 与键对应的是一个消息字符串的 Map, 该 Map 的键就是消息键,值就是消息内容
  8. *
  9. * @param refer
  10. * 参考值。来自 '@Localization.value'
  11. * @return 多国语言字符串的 Map
  12. */
  13. Map<String, Map<String, Object>> load(String refer);
  14. }

你声明在 '@Localization' 中的 "value" 的值,会被传入这个接口,作为 refer 参数的值

让 Ioc 容器管理你的 MessageLoader

通过beanName进行设置:

  1. ...
  2. @Localization( type=MessageLoader.class,
  3. beanName="myMessages",
  4. value="msg" )
  5. public class MainModule {
  6. ...

提供了 "beanName" 属性,这样,Nutz.Mvc 将从 Ioc 容器中加载名字为 "myMessages" 的对象。当然它的类型实现了 "MessageLoader" 接口

本页面的文字允许在知识共享 署名-相同方式共享 3.0协议GNU自由文档许可证下修改和再使用。

原文: http://nutzam.com/core/mvc/localization.html