本篇教程中,我们将探究使用Struts2的消息资源功能(也被称为资源包)。消息资源对于将应用所输出的文本放置到页面上、创建表单域标签、基于用户的地区改变文本到指定的语言等需求,提供了一条简单的途径。
在一个Struts2的网页应用中,读者可以通过创建一个与动作类相同名称、扩展名为extension的属性文件,将一个消息资源属性文件关联到Struts2动作类。这个属性文件必须与动作类在相同的包之中。对于本篇教程的示例,假设希望把表单域标签放置到一个单独的文件,这样可以轻松地改变它们,并且提供以其它语言显示的功能。 如果读者已经完成了《表单验证 (Form Validation)》教程,可以在它的示例项目的基础上继续进行。 将以下文本写入存放在register.java同目录、名为register.properties的文件。
以上是个标准的Java属性文件。等号“=”左边是键、右边是值,组成了键值对。当Register动作被执行,通过引用键的名称,这些属性在页面上可用。 译者注: 1.Register.properties的文件名“Register”要与动作类的.java文件名完全一致,包括大小写;否则Struts2将无法找到这个properties文件。 2.properties文件请先空两行,否则第一个键值对可能出现无法识别的问题。 3.如果新建properties文件并输入中文的值,页面上会展示为乱码;每个中文汉字必须用“\u90AE”这种形式才行。
Struts2键属性可以在textfield标签中使用,来指示Struts2框架作用于textfield的name与标签属性的值。不是直接提供这些属性和它们的值,读者可以仅仅使用键属性。 如果打开《表单验证》教程中的register.jsp文件,读者会看到如下的Struts2的textfield标签:
除了指定name以及标签的属性,读者也可以仅使用键属性。
键属性的值指示Struts2框架对name属性使用相同的值(personBean.firstName);对标签属性的值,通过Struts2框架在属性文件中用相同的值找到的键,这个键属性的值被使用。在这里的示例中,Struts2将会在Register.properties里,搜索personBean.firstName这个键的值。键的值是First name,会被作为标签属性的值使用。 为了让键属性找到属性文件,页面的显示必须是执行一个Struts2动作类的结果。现在,如果读者检查《表单验证》教程里index.jsp指向register.jsp页面的链接,是一个标准URL,如下。
我们需要将上面这个链接改变,这样它通往Register.jva的Struts2动作类。将上述链接替换:
我们使用Struts2 url标签来创建指向registerInput的动作。我们现在使用这个链接,作为href属性的值。我们也必须在struts.xml中定义registerInput动作。添加以下代码到struts.xml中。
上述的动作结点指示Struts2框架执行Register类的input方法来响应registerInput这个动作。input方法是Register从类ActionSupport继承而来。继承而来的input方法,其默认的行为是返回字符串“input”。上述的result结点指定了返回的结果是“input”时,渲染register.jsp。 通过完成上述的一堆工作,register.jsp页面将会读取在Register.properties文件中的属性。Struts2框架将会让定义在Register.properties中的这些属性对于页面可用,因为页面是在Register.java(Struts2的动作类)被执行之后才渲染的。 跟随项目文件的指引(README.txt),创建war文件,并且将war文件拷贝到读者自己的servlet容器。打开一个网页浏览器,导航README文件指定的到首页。当把鼠标放在“注册”的超链接上时,回看到指向registerInput.action的链接。
当点击“注册”链接,浏览器回显示register.jsp。表单域标签会是Register.properties文件中,键对应的值。 (此处有截图)
我们也可以使用Struts2的text标签来从properties文件中显示值。在thankyou.jsp文件中添加这个text标签代替原有的h3标签。
因为thankyou.jsp也是在Register.java动作类执行之后渲染的,所以thankyou键以及它的值对于页面也是有效的。(懒得弄截图了) 如何让在输入域输入的名字显示在thankyou.jsp页面?回来看Register.properties文件里,thankyou键的值。
“%{personBean.firstName}”标记告诉Struts2,用由一个Person对象返回的,调用getPersonBean的结果来代替这个部分。然后调用会返回一个字符串(用户在register.jsp的表单域中对personBean.firstName输入的值)的getFirstName方法。
(译者注:上面搞了半死,Register.properties文件只能给Register这一个动作用,其它动作都不行)。那么,如果读者希望拥有了键和值的properties文件能够被多个页面所引用、并且这些是在执行了不同的动作类之后渲染的页面呢?Struts2能够让多个属性文件在包结构中被找到的能力。 将以下内容放到名为package.properties的文件中,并将文件保存在org.apache.struts src/main/resources的包org.apache.struts。
现在,任何被org.apache.struts结构范围内动作所渲染的页面,可以使用一个Struts2name属性值为“greeting”的文本标签,来显示greeting键的值。例如,添加一下标记到helloworld.jsp文件中,在h2标签之前。
重新构建项目并应用到容器中。访问index.action,点击Hello World的链接,会看到: 对于包含了package.properties文件的包,其结构里任何动作执行之后渲染的页面,在package.properties中定义的属性的键和值都是可用的。
读者也可以在struts.xml中指定全局属性文件。在这个属性文件中定义的键值对,对于所有执行某个动作后渲染的页面都是有效的。 将以下内容添加到名为“global.properties”的文件中(但注意,文件名并不一定要是“global”)。
在src/main/resources路径下保存global.properties文件。 为了向Struts2提示global.properties文件的存在,将以下结点添加到struts.xml文件里,constant结点之后。
为了在页面中使用contact键,将以下标记添加到index.jsp文件中,body标记结束之前。
再重新构建项目、扔进容器、访问index.action,会看到…… Struts2会在所有匹配当前动作类的属性文件中搜索contact属性键,然后在所有归属于动作类所在包结构中的属性文件中搜索,然后在任何struts.xml文件中指定的属性为嗯见中搜索。对于本示例,Struts2会在global.properties中找到contact键。contact键的值会被显示于放置了对应文本标签的位置。 当然,可以把对应的文本标签加入到本示例中的所有JSP中。
使用信息资源文件也让读者可以用不同的语言提供文本。默认情况下,Struts2会使用用户默认区域语言。如果区域是英语(en),使用的属性文件回事没有区域制定的(例如Register .properties)。如果不是英语区、但使用西班牙语(es),那么Struts2会搜索名为Register_es.properties的属性文件。 Struts2支持i18n的支持示例:创建一个名为Register_es.properties的文件,并在其中写入以下西班牙语的译文。
将Register_es.properties文件保存在与Register.properties相同的路径。 在我们的示例应用中,我们需要告诉Struts2使用es的区域值(因为我们并不处在西语区)代替默认的区域值(就是en)。将以下标记添加到index.jsp。
在上面内容里,我们已经添加了一个名为request_locale的参数到URL;这个参数的取值是es。对这个URL响应的动作类(Register.java)回督导区域值是es,于是会搜索带有“_es”的properties文件(例如Register_es.properties)。动作类会使用那些属性文件来找到被页面引用的,正确键的值(例如personBean.firstName)。 在点击“注册”链接后,会看到相同的页面,但标签处显示的是西班牙文。如果我们通过创建global.properties和package.properties文件的_es.properties版本,那我们就可以创建完整的西班牙语版本注册页面。
本篇教程讲解了如何在Struts2中使用消息资源,介绍了如何启用Struts2的国际化。为了完整地理解这些概念、并学习更多关于Struts2,请阅读http://struts.apache.org上的文档们吧。