- 资源文件的命名
- 资源文件基名的指定
- struts.xml 文件指定资源文件的基名
- struts.properties 文件指定资源文件的基名
- 通过标签 i18n 指定资源文件的基名
- 资源文件的位置
- 包级资源文件
- 类级资源文件
- 全局级资源文件
- 默认资源文件
- 资源文件的加载顺序
- Action 中加载资源文件
- 在 JSP 中访问资源文件
- 怎么获取资源文件中指定key的值
- s:text
- s:submit
- s:textfield
- s:password
- s:radio
- 在自定义的 Action 中获取资源文件中指定 key 的值
- ActionSupport
- 资源文件中消息值中的占位符
- 消息值中使用表达式
- 设置和获取默认的语言环境
- 拦截器 i18n
- 案例演示
- 案例一
- 案例二
- 参考文章
资源文件的国际化 internationalization,这个单词是以 i 开头 n 结尾,中间共 18 个字母,所以缩写为 i18n,国际化的核心:页面显示的文字语言是可配置的。
Struts2 国际化是建立在 Java 国际化的基础上的,一样是通过提供不同语言环境的消息资源(资源属性文件),然后通过ResourceBundle 加载指定 Locale 对应的资源文件,再取得该资源文件中指定 key 对应的消息(值),其整个过程与 JAVA 程序的国家化完全相同,只是 Struts2 框架对 JAVA 程序国际化进行了进一步封装,从而简化了应用程序的国际化。
资源文件的命名资源文件必须是 properties 文件,命名规则为:基名 _语言代号_地区代号(即国家代号).properties
。
基名是需要指明出来的,例如,资源文件名称为 globalMessages_en_US.properties,那么基名 globalMessages 可以在配置文件 struts.xml 中指明出来,如下所示:
上述方式指定的是全局性的资源文件。
struts.properties 文件指定资源文件的基名struts.custom.i18n.resources=baseName
struts.i18n.encoding=GBK
上述方式指定的是全局性的资源文件。
通过标签 i18n 指定资源文件的基名如果不在配置文件 struts.xml 中指明,也可以通过 i18n 标签来指明,如下所示:
标签 i18n 的属性 name 就是用来指明资源文件的基名。标签体中的标签 text 的属性 name 指定 key 的名称。
指明了基名之后呢, 这个标签的底层代码,会调用 Action 的某个方法,这个方法会根据当前系统的语言环境去读取名称以 globalMessages 开头的资源文件,获取 key 为 firstname 的值,如果获取不到,则会到配置文件 struts.xml 或者 struts.properties 所指定的资源文件中获取 key 为 firstname 的值,如果还是找不到则会直接输出属性 name 的值到页面中(即直接输出 key 的名称)。
如果项目非常大,所有资源文件放入同一个目录下是不好的。资源文件需要分层和分类。
Maven 项目中,资源文件只能放在目录 resources 下。其实除了包级别资源文件和类级别资源文件的位置有强制要求外,全局级别的资源文件可以存放在目录 classes 中的任意位置上。只是在 struts.xml 需要指定资源文件的具体路径罢了。
如下图展示在 Maven 项目中将资源文件存放在 LoginAction 所在包目录下: 在 struts.xml 要指明资源文件的具体路径:
如下图展示了 eclipse 中如何存放资源文件:
上图所示的包级资源文件 package_zh_CN.properties 能被 com.tarena.com.outman.day05 下所有 Action 使用;包级资源文件 package_zh_CN.properties 能被 com.tarena.com.outman 下所有 Action 使用;类级资源文件 OneAction_zh_CN.properties 只能被 com.tarena.com.outman.day05 下的 OneAction 访问。
包级资源文件存放在某个包下面的资源文件。命名规则:package_language_country.properties,其中 package 就是固定的基名。
表示某资源文件是被一个包中所有 Action 所使用的。 包级资源文件是其所在包及子包中的所有 Action 共享的资源文件。
Maven 项目中, 必须将资源文件存放在目录 resources 下面,如果要创建包级资源文件,那么要先在目录 resources 下面创建对应的包目录,然后在该包目录下创建资源文件,在构建项目时会将资源文件复制到 classes 目录中相对应的包目录下。
struts.xml 文件中不需要指定资源文件的基名。如下图所示指定包级资源文件的基名也可以,是因为查找包级资源文件时根本就不会去解析常量 struts.custom.i18n.resources 的值。这个常量是用来指定全局级别的资源文件的基名的。
以某个类名命名的资源文件。命名规则:ActionName_language_country.properties,其中 ActionName 是 Action 类的类名,也就是以 Action 类的类名作为资源文件的基名。
表示某资源文件只能被指定类使用。 类级资源文件是指定类专享的资源文件。
下图展示 Maven 项目如何存放类级资源文件: 类级别的资源文件,不需要在 struts.xml 中指定资源文件的基名。
全局级资源文件直接存放在目录 resources 下即可。
全局级的资源文件,必须通过文件 struts.xml 或者 struts.properties 指定资源文件的基名,否则找不到资源文件:
当在中文操作系统下,如果 myres_zh_CN.properties、myres.properties 两个文件都存在,则优先会使用 myres_zh_CN.properties,当myres_zh_CN.properties 不存在时候,会使用默认的 myres.properties。没有提供语言和地区的资源文件则会去读取系统默认的资源文件。
资源文件都必须是 ISO-8859-1 编码,因此,对于所有非西方语系的处理,都必须先转换为 Java Unicode Escape 格式。转换方法是通过 JDK 自带的工具 native2ascii。
资源文件的加载顺序 Action 中加载资源文件假设我们在 ChildAction 中调用了 getText("title")
,Struts 2.0 将会按下面的顺序来加载资源文件:
(1)优先加载系统中 ChildAction 类文件所在目录下的,且 baseName 为 ChildAction 的系列资源文件。
(2)如果在(1)中找不到指定 key 对应的消息值,且 ChildAction 有父类 ParentAction,则加载 ParentAction 类文件所在目录下的,且 baseName 为 ParentAction 的系列资源文件。
(3)如果在(2)中找不到指定 key 对应的消息值,且 ChildAction 有实现接口 IChildAction,则加载 IChildAction 类文件所在目录下的,且 baseName 为 IChildAction 的系列资源文件。
(4)如果在(3)中找不到指定 key 对应的消息值,且 ChildAction 有实现接口 ModelDriven(即使用模型驱动模式),则对于 getModel()方法返回的 model 对象,重新执行第(1)步操作。
(5)如果在(4)中找不到指定 key 对应的消息值,则加载 ChildAction 类文件所在目录下的,且 baseName 为 package 的系列资源文件。
(6)如果在(5)中找不到指定 key 对应的消息值,则沿着当前包上溯,直到最顶层包去查找 baseName 为 package 的系列资源文件。
(7)如果在(6)中找不到指定 key 对应的消息值,则查找以常量 struts.custom.i18n.resources 的值作为 baseName 的系列资源文件。
(8)如果经过上面的步骤一直找不到 key 对应的消息值,将直接将 key 的名称输出。
在 JSP 中访问资源文件对于在 JSP 中访问国际化消息,则简单的多,可以分为两种形式:
1.使用 标签作为父标签 (1)从
标签指定的国际化资源文件中读取指定 key 对应的消息值。 (2)如果在(1)中找不到指定 key 对应的消息值,则查找以常量 struts.custom.i18n.resources 的值作为基名的系列资源文件。 (3)如果经过上面步骤还是找不到指定 key 对应的消息值,则直接将 key 的名称输出。
2.没使用 标签作为父标签
直接查找以常量 struts.custom.i18n.resources 的值作为基名的系列资源文件,如果找不到指定 key 对应的值,则直接将 key 的名称输出。
怎么获取资源文件中指定key的值 s:text这个标签的属性 name 是用来指定显示在页面上的文本。
这个标签的底层代码,会调用 Action 的某个方法,这个方法会根据当前系统的语言环境去读取资源文件,然后查找名为 firstname 的 key,找到则将该 key 的值返回,找不到就直接输出属性 name 的值到页面中。
这个标签是通过EL 表达式去调用 Action 的方法 getText() 来获取名为 login 的 key 对应 的值。
getText() 这个方法来自于类 ActionSupport,这个方法的处理逻辑是这样的:
1.先获取 request 中的参数 request_locale,如果获取不到,则会到 session 对象中获取名为 WW_TRANS_I18N_LOCALE 的 key 对应的值,判断用户所使用的语言是哪种
2.根据获取到的语言和指明的资源文件基名到目录 classes 下面读取资源文件,获取并返回指定 key 的值,如果找不到则返回 null。
调用的是谁的 getText()?请求的是 LoginAction,转发到 login.jsp,那么这个 jsp 中获取资源文件中的值的有关标签调用的就是 LoginAction 的 getText()。
这个标签还可以通过属性 key 来指定资源文件中相对应的 key 的名称,从而获得相对应的国际化信息,如下所示:
s:textfield
这个是文本输入框,属性 name 是用来指定参数名称。属性 label 是用来指定显示在页面中的文本。
通过调用 Action 的方法 getText() 方法来获取资源文件中的值,如下所示:
属性 label 指定 EL 表达式,调用 Action 的方法 getText() 去国际化资源文件中获取名为 firstname 的 key 对应的值。
还可以通过属性 key 来指定资源文件中的 key,如下所示:
s:password
这是密码文本输入框。
通过调用 Action 的方法 getText() 方法来获取资源文件中的值,如下所示:
通过属性 key 来指定资源文件中的 key,如下所示:
s:radio
单选框
属性 name 指定参数名;属性 list 指定遍历的集合,集合中的元素有两个属性,左边属性指定元素 radio 的属性 value 的值,右边属性则指定元素 label 的文本内容。
通过 Action 的方法 getText 获取资源文件中指定 key 的值,如下所示:
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?