您的位置:首页 > 编程语言 > Java开发

【Struts2】struts2学习(3) 资源国际化

2017-05-02 17:45 351 查看
Struts 2 的国际化


Struts 2 加载全局资源文件
 
加载全局的国际化资源文件的方式通过配置常量来实现。可以在Struts2.xml或者struts.properties文件中配置常量,需要配置struts.custom.i18n.resources常量,该常量的值为全局国际化资源文件的baseName.
struts.properties文件中指定一行

struts.custom.i18n.resources=messageResource在struts.xml文件中配置
<constant name=”struts.custom.i18n.resources” value=”messageResource”/>
配置之后,Struts2 应用可以在JSP页面或者Action中取出这些国际化资源文件。

访问国际化消息
1.      在JSP页面中输出国际化消息,可以使用Struts2的<s:text …/> 标签,该标签可以指定一个name属性,该属性指定了国际化资源文件中的key。
2.      在Action类中访问国际化消息,可以使用ActionSupport类的getText方法,该方法可以接受一个name参数,该参数制定了国际化资源文件中的key。
3.      为了在表单元素的Label里输出国际化消息。可以为该表单标签指定一个key属性,该key指定了国际化资源文件中的key。
例:
创建资源文件 mess_en_US.properties  mess表明了该国际化资源文件的baseName是mess。
loginPage=Login Page
errorPage=Error Page
succPage=Welcome Page
failTip=Sorry,You can't log in!
succTip=welcome,you has logged in!
user=User Name
pass=User Pass
login=Login
中文资源文件mess.properties
loginPage=登录页面
errorPage=错误页面
succPage=成功页面
failTip=对不起,你不能登录!
succTip=欢迎,你已经登录!
user=用户名
pass=密码
login=登录

包含非西欧的国际化资源文件必须使用native2ascii工具进行处理,将处理后的文件命名为mess_zh_CN.properties  把这几个文件放在src目录下。

log.jsp页面,通过key来访问国际化资源,系统会根据浏览者所在的Locale来加载对应的语言资源文件。
<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<%@taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<!-- 使用s:text标签输出国际化消息 -->
<title><s:text name="loginPage"/></title>
</head>
<body>
<s:form action="Login">
<!-- 在表单元素中使用key来指定国际化消息的key -->
<s:textfield name="username" key="user"/>
<s:textfield name="password" key="pass"/>
<s:submit key="login"/>
</s:form>
</body>
</html>

访问界面,并把语言、区域修改为美国英语。





在Action中访问国际化消息,则可以利用ActionSupport类的getText方法。
LoginAction.java
public class LoginAction extends ActionSupport
{
//定义封装请求参数的两个属性
private String username;
private String password;
public String execute() throws Exception
{
ActionContext ctx = ActionContext.getContext();
if (getUsername().equals("li")
&& getPassword().equals("meng") )
{
ctx.getSession().put("user" , getUsername());
ctx.put("tip" , getText("succTip"));
return SUCCESS;
}
else
{
ctx.put("tip" , getText("failTip"));
return ERROR;
}
}
}

输出带占位符的国际化消息

Struts 2中提供了如下两种方式来填充消息字符串中占位符。
1.      如果需要在JSP页面中填充国际化消息里的占位符,则可以通过在<s:text …/>标签中使用多个<s:param …/>标签来填充消息中的占位符,第一个<s:param…/>标签指定第一个占位符值,第二个指定第二个
2.      如果需要在Action中填充国
4000
际化消息里的占位符,则可以通过在调用getText方法时使用getText(String aTextName,List args) 或 getText(Stringkey,String[] args) 方法来填充占位符。第二个参数可以是一个字符串数组,也可以是字符串组成的List对象。
 
例:
有如下三条国际化消息
failTip={0},Sorry,You can't log in!
succTip={0},Welcome,you has logged in!
welcomeMsg={0},Hello!Now is {1}!
中文消息为:
failTip={0},对不起,你不能登录!
succTip={0},欢迎,你已经登录!
welcomeMsg={0},你好!现在时间是{1}!

在Action中调用ActionSupport类的getText方法,并传入占位符的参数值。

LoginAction.java
public class LoginAction extends ActionSupport
{
//封装用户请求参数的username和password属性
private String username;
private String password;
public String execute() throws Exception
{
ActionContext ctx = ActionContext.getContext();
if (getUsername().equals("li")
&& getPassword().equals("meng") )
{
ctx.getSession().put("user" , getUsername());
//根据key取出国际化消息,并为占位符指定值。
ctx.put("tip" , getText("succTip" , new String[]
{getUsername()}));
return SUCCESS;
}
else
{
//根据key取出国际化消息,并为占位符指定值。
ctx.put("tip" , getText("failTip", new String[]
{getUsername()}));
return ERROR;
}
}
}

为了在JSP页面中输出带两个占位符的国际化消息,只需要为<s:text …/> 标签指定两个<s:param …/>子标签。

welcome.jsp
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title><s:text name="succPage"/></title>
</head>
<body>
${requestScope.tip}<br/>
<jsp:useBean id="d" class="java.util.Date" scope="page"/>
<s:text name="welcomeMsg">
<s:param><s:property value="username"/></s:param>
<s:param>${d}</s:param>
</s:text>
</body>
</html>


除了上面这种方式,Struts2还提供了对占位符的一种替代方式,这种方式允许直接在国际化消息中使用表达式,使用这种方式,可以避免在使用国际化消息时需要为占位符传入参数值。

failTip=${username},对不起,你不能登录!
succTip=${username},欢迎,你已经登录!
welcomeMsg=${username},你好!现在时间是{0}!
修改LoginAction类的execute方法。
public String execute() throws Exception
{
ActionContext ctx = ActionContext.getContext();
if (getUsername().equals("li")
&& getPassword().equals("meng") )
{
ctx.getSession().put("user" , getUsername());
//根据key取出国际化消息,并为占位符指定值。
ctx.put("tip" , getText("succTip" ));
return SUCCESS;
}
else
{
//根据key取出国际化消息,并为占位符指定值。
ctx.put("tip" , getText("failTip”));
return ERROR;
}
}

通过使用表达式,可以从ValueStack中取出该username属性值,自动填充到该消息资源中。

加载资源文件的方式
上为加载国际化资源最常用的方式,此外,Struts2还有指定包范围资源文件、Action范围资源文件、以及临时指定资源文件等。
 
包范围资源文件
大型项目中,有大量内容需要国际化,如果把所有国际化资源文件放到同一个全局文件里,将非常难以维护。
为Struts 2 应用指定包范围资源文件的方法是:在包的根路径下建立多个文件名为
package_language_country.properties的文件,一旦建立了这个系列的国际化资源文件,应用中处于该包下的所有Action都可以访问该资源文件。
注意:包范围资源文件的baseName就是package,不是Action所在的包名。
添加资源文件 package_zh_CN.properties
failTip=包范围消息:对不起,你不能登录!
succTip=包范围消息:欢迎,你已经登录!
package_en_US.properties
failTip=Package Scope:Sorry,You can't log in!
succTip=Package Scope\:welcome,you has logged in\!



运行程序,我们得出一个结论:Action将优先使用包范围内的资源文件。
Action范围资源文件
Struts 2允许为Action单独指定一份国际化资源文件。为Action单独指定一份资源文件的方法是:在Action类文件所在的路径建立多个文件名为ActionName_language_country.properties的文件,这系列资源文件只能由该Action来访问。资源文件和类在同一位置。
LoginAction_en_US.properties

failTip=Action Scope:Sorry,You can't log in!
succTip=Action Scope:welcome,you has logged in!
指定资源文件后,Action将优先加载Action范围内的资源文件。
临时指定资源文件
临时指定资源文件的方式,可以在JSP页面中输出国际化消息时临时指定国际化资源的位置。需要使用Struts的另一个标签 <s:i18n …/>
如果把<s:i18n …/>标签作为<s:text…/>标签的父标签,则<s:text …/> 标签将会直接加载<s:i18n …/> 标签里指定的国际化资源文件;如果把<s:i18n …>作为表单的父标签,则表单标签的key属性将会从国际化资源文件中加载该消息。
创建资源文件 tmp.properties
loginPage=临时消息:登录页面
errorPage=临时消息:错误页面
succPage=临时消息:成功页面
failTip=临时消息:全局消息:对不起,您不能登录!
succTip=临时消息:全局消息:欢迎,您已经登录!
user=临时消息:用户名
pass=临时消息:密 码
login=临时消息:登录
tmp_en_US.properties
loginPage=Temp Message:Login Page
errorPage=Temp Message:Error Page
succPage=Temp Message:Welcome Page
failTip=Temp Message:Global Message:Sorry,You can't log in!
succTip=Temp Message:Global Message:welcome,you has logged in!
user=Temp Message:User Name
pass=Temp Message:User Pass
login=Temp Message:Login
在login.jsp中指定临时资源文件。
<s:i18n name="tmp">
<title><s:text name="loginPage"/></title>
</s:i18n>
</head>
<body>
<s:i18n name="tmp">
<s:form action="Login">
<s:textfield name="username" key="user"/>
<s:textfield name="password" key="pass"/>
<s:submit key="login"/>
</s:form>
</s:i18n>



Struts 2加载资源文件顺序
假设在ChildAction中访问国际化消息。
1.      优先加载系统中保存在ChildAction的类文件相同位置,且baseName 为ChildAction的系列资源文件。
2.      如果 1中找不到指定key的对应消息,且ChildAction有父类ParentAction,则加载系统中保存在ParentAction的类文件相同位置,且baseName为ParentAction的资源文件。
3.      如果在 2 中找不到key对应的消息,且ChildAction有实现接口IChildAction,则加载系统中保存在IChildAction的类文件相同位置,且baseName为IChildAction的系列资源文件。
4.      如果在 3 中找不到指定key对应的消息,且ChildAction有实现接口ModelDreven(模型驱动模式),则对于getModel()方法返回的model对象,重新执行第1不操作。
5.      如果在 4 中找不到key对应的消息,则查找当前包下baseName为package的系列资源文件。
6.      如果在 5 中找不到指定key对应的消息,则沿着包上溯,直到顶层包来查找baseName为package的系列资源文件。
7.      如果在 6 中找不到指定key对应的消息。则查找struts.custom.i18n.resources常量指定的baseName系列资源文件。
8.      如果经过上面的步骤一直找不到该key对应的消息,将直接输出该key的字符串值,如果在1-7中找到了,则停止搜索。
 
Jsp访问国际化消息,分为两种形式。
对于使用<s:i18n …/>标签作为父标签的<s:text …>标签。表单标签的形式。
1.      从<s:i18n…/>指定的国际化资源文件中加载key对应的消息。
2.      如果在 1 中找不到key对应的消息,则查找struts.custom.i18n.resource 常量指定的baseName的系列资源文件。
3.      找不到key值,则直接输出key的字符串值,找到则停止搜索。
 
没有使用<s:i18n …/>标签作为父标签
直接加载struts.custom.i18n.resources常量指定baseName的系列资源文件。如果找不到,则输出该key对应的字符串值。
Demo地址:https://github.com/CoderMengLi/Struts_Demo3
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息