`

Struts 2 的国际化(二)

阅读更多

 

二、 Struts 2 的国际化入门

 

    Struts 2 国际化是建立在 Java 国际化的基础之上,一样也是通过提供不同国家/语言环境的消息资源,然后通过 ResourceBundle 加载指定 Locale 对应的资源文件,再取得该资源文件中指定 key 对应的消息。整个过程与 Java 程序的国际化完全相同,只是 Struts 2 框架对 Java 程序国际化进行了进一步封装,简化。


2.1 加载全局资源文件

 

    Struts 2 提供了很多加载国际化资源文件的方法,最简单、最常用的就是加载全局的国际化资源文件这种方式是通过配置常量来实现不管在 struts.xml ,还是在 struts.properties 文件中配置常量,只需要配置 struts.custom.i18n.resources 常量即可

 

假设系统需要加载的国际化资源文件的 baseName 为 messageResource,则:

struts.properties

struts.custom.i18n.resources=messageResource
 

struts.xml

<constant name="struts.custom.i18n.resources" value="messageResource"/>

 

通过这种方式加载国际化资源文件后,Struts 2 应用就可以在所有地方取出这些国际化资源文件了,包括 JSP 和 Action

 

2.2 访问国际化消息

 

  Struts 2 既可以在 JSP 页面中通过标签输出国际化消息,也可以在 Action 类中输出国际化消息。

 

  Struts 2 访问国际化消息主要有如下 3 种方式:

●  JSP 页面,可以使用 Struts 2 的 <s:text .../> 标签,该标签可以指定一个 name 属性,该属性指定了国际化资源文件中的 Key

●  Action 类中,可以使用 ActionSupport 类的 getText() 方法,该方法接受一个 name 参数,该参数指定了国际化资源文件中的 Key

●  表单元素Label 里输出国际化信息 ,可以为该表单标签指定一个 key 属性,该 key 指定了国际化资源文件中的 Key

 

messageResource_en_US.properties

#资源文件的内容就是key-value对
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

messageResource_zh_CN.properties

loginPage=登录页面
errorPage=错误页面
succPage=成功页面
failTip=对不起,您不能登录!
succTip=欢迎,您已经登录!
user=用户名
pass=密  码
login=登录
 

上面 messageResource_zh_CN.properties 文件必须使用 native2ascii 工具处理。

 

提供上面 2 份资源文件后,通过上一节所介绍的方式加载国际化资源文件,系统会根据浏览者所在的 Locale 来加载对应的语言资源文件。

 

login.jsp

<%@ 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>
	<title><s:text name="loginPage"/></title>
	<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<s:form action="login">
	<s:textfield name="username" key="user"/>
	<s:textfield name="password" key="pass"/>
	<s:submit key="login"/>
</s:form>
</body>
</html>
 

上面 JSP <s:text .../> 标签直接输出国际化信息,也通过表单元素中指定 key 属性来输出国际化消息 。通过这种方式,就可以完成 JSP 中普通文本、表单元素标签的国际化。

 

如果在 Action 中,可以用 ActionSupport getText() 方法

LoginAction.java

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ActionContext;

public class LoginAction extends ActionSupport
{
	//封装两个请求参数的属性
	private String username;
	private String password;

	//username属性的setter和getter方法
	public void setUsername(String username)
	{
		this.username = username;
	}
	public String getUsername()
	{
		return this.username;
	}

	//password属性的setter和getter方法
	public void setPassword(String password)
	{
		this.password = password;
	}
	public String getPassword()
	{
		return this.password;
	}

	//定义处理用户请求的execute方法
	public String execute()throws Exception
	{
		ActionContext ctx = ActionContext.getContext();
		//用户登录成功
		if (getUsername().equals("crazyit")
			&& getPassword().equals("leegang") )
		{
			ctx.getSession().put("user" , getUsername());
			//调用getText方法取出国际化消息
			ctx.put("tip" , getText("succTip"));
			return SUCCESS;
		}
		else
		{
			//调用getText方法取出国际化消息
			ctx.put("tip" , getText("failTip"));
			return ERROR;
		}
	}
}
 

通过这种方式,即使 Action 需要设置在下一个页面显示的信息,也无需直接设置字符串常量,而是使用国际化消息的 key 来输出,从而实现程序的国际化。

 

struts.xml

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
	"http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
	<constant name="struts.custom.i18n.resources"
		value="messageResource"/>
	<constant name="struts.i18n.encoding" value="GBK"/>

	<package name="lee" extends="struts-default">
		<action name="login" class="lee.LoginAction">
			<result name="error">/error.jsp</result>
			<result>/welcome.jsp</result>        
		</action>
		<action name="">
			<result>.</result>        
		</action>
	</package>
</struts>

 

welcome.jsp

<%@ 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>
	<title><s:text name="succPage"/></title>
	<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
	${requestScope.tip}
</body>
</html>

 error.jsp

<%@ 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>
	<title><s:text name="errorPage"/></title>
	<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
	${requestScope.tip}
</body>
</html>
 

 

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

 

Java 中使用 MessageFormat 类,完成填充占位符

 

Struts 2 更方便,提供 2 种方式 来填充消息字符串中的占位符

 

 JSP 页面中,则可以通过 <s:text .../> 标签中使用多个 <s:param ...> 标签来填充消息中的占位符。第一个 <s:param ...> 指定第一个占位符值,第二个 <s:param ...> 指定第二个占位符值,依此类推 

 Action 中,则可以通过在调用 getText(String aTextName , List args) getText(String key , String[] args) 方法来填充占位符。

 

 

例如:

messageResource_zh_CN.properties

loginPage=登陆页面
errorPage=错误页面
succPage=成功页面
failTip={0},对不起,您不能登录!
succTip={0},欢迎,您已经登录!
welcomeMsg={0},您好!现在时间是{1}!
user=用户名
pass=密  码
login=登陆

 messageResource_en_US.properties

loginPage=Login Page
errorPage=Error Page
succPage=Welcome Page
failTip={0},Sorry,You can't log in!
succTip={0},Welcome,you has logged in!
welcomeMsg={0},Hello!Now is {1}!
user=User Name
pass=User Pass
login=Login
  

LoginAction.java

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ActionContext;

public class LoginAction extends ActionSupport {
    // 定义两个属性,username和password,用于封装两个请求参数
    private String username;

    private String password;

    // username属性的setter和getter方法
    public void setUsername(String username) {
        this.username = username;
    }

    public String getUsername() {
        return this.username;
    }

    // password属性的setter和getter方法
    public void setPassword(String password) {
        this.password = password;
    }

    public String getPassword() {
        return this.password;
    }

    // 下面省略了两个属性的setter和getter方法
    // ...

    // 定义处理用户请求的execute方法
    public String execute() throws Exception {
        ActionContext ctx = ActionContext.getContext();
        // 用户登录成功
        if (getUsername().equals("crazyit") && getPassword().equals("leegang")) {
            ctx.getSession().put("user", getUsername());
            // 调用getText方法取出国际化信息,使用字符串数组为占位符设置值
            ctx.put("tip", getText("succTip", new String[]{username}));
            return SUCCESS;
        } else {
            // 调用getText方法取出国际化信息,使用字符串数组为占位符设置值
            ctx.put("tip", getText("failTip", new String[]{username}));
            return ERROR;
        }
    }
}
 

welcome.jsp

<%@ 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>
	<title><s:text name="succPage"/></title>
	<meta name="website" content="http://www.crazyit.org" />
</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>

 

上面页面 使用 ${requestScope.tip} 输出 Action类 中取出的国际化消息,通过 <s:text .../> 取出另一个国际化消息,使用 2 个 <param .../> 指定 2 个占位符的值

 

login.jsp

<head>
	<title><s:text name="loginPage"/></title>
	<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<s:form action="login">
	<s:textfield name="username" key="user"/>
	<s:textfield name="password" key="pass"/>
	<s:submit key="login"/>
</s:form>
</body>
 

struts.xml

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
	"http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
	<constant name="struts.custom.i18n.resources"
		value="messageResource"/>
	<constant name="struts.i18n.encoding" value="GBK"/>

	<package name="lee" extends="struts-default">
		<action name="login" class="lee.LoginAction">
			<result name="error">/error.jsp</result>
			<result>/welcome.jsp</result>        
		</action>
		<action name="">
			<result>.</result>        
		</action>
	</package>
</struts>
 

 

除此之外,Struts 2提供了对占位符的一种替代方式

这种方式可以避免在使用国际化消息时还需要为占位符传入参数值,如下:

 

#在消息资源中使用表达式
failTip=${username},对不起,您不能登录!
succTip=${username},欢迎,您已经登录!

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


这种方式,当需要 Action 中使用该消息资源时,无需为该消息资源传入参数,即当使用 getText() 方法获取国际化消息时,无需为消息资源中的占位符传入参数

 

 

三、 加载资源文件的不同方式


  前面介绍了最常见的方式,除此之外,Struts 2 还提供了多种方式来加载国际化资源文件,包括指定包范围资源文件 类范围资源文件 临时指定资源文件 等。

 

 

3.1 包范围资源文件

 

   把所以国际化资源都放在同一个全局文件里,文件会过大。为了更好地体现软件工程里 分而治之 的原则,Struts 2 允许针对不同模块、不同 Action 来组织国际化资源文件。


包范围资源文件: 在包的根路径下建立多个文件名为 package_language_country.properties 的文件,一旦建立了这个系列的国际化资源文件,应用中处于该包下的所有 Action 都可以访问该资源文件。

 

注意: 上面的包范围资源文件的 baseName 就是 package ,不是 Action 所在包名。该文件通常只需放在该包的根路径下即可

 

lee.action 下 有 LoginAction.java

package lee.action;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ActionContext;

public class LoginAction extends ActionSupport
{
	//下面定义了两个属性,用于封装请求参数
	private String username;
	private String password;
	//此处省略了各属性的setter和getter方法

	//username属性的setter和getter方法
	public void setUsername(String username)
	{
		this.username = username;
	}
	public String getUsername()
	{
		return this.username;
	}

	//password属性的setter和getter方法
	public void setPassword(String password)
	{
		this.password = password;
	}
	public String getPassword()
	{
		return this.password;
	}

	//处理用户请求的execute方法
	public String execute() throws Exception
	{
		ActionContext ctx = ActionContext.getContext();
		if (getUsername().equals("crazyit")
			&& getPassword().equals("leegang"))
		{
			ctx.getSession().put("user" , getUsername());
			//取出国际化消息
			ctx.put("tip" , getText("succTip"));
			return SUCCESS;
		}
		else
		{
			//取出国际化消息
			ctx.put("tip" , getText("failTip"));
			return ERROR;
		}
	}
}

 

struts.xml  

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
	"http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
	<constant name="struts.custom.i18n.resources"
		value="messageResource"/>
	<constant name="struts.i18n.encoding" value="GBK"/>

	<package name="lee" extends="struts-default">
		<action name="login" class="lee.action.LoginAction">
			<result name="error">/error.jsp</result>
			<result>/welcome.jsp</result>        
		</action>
		<action name="">
			<result>.</result>        
		</action>
	</package>
</struts>
 

lee 下 有:package_en_US.properties

failTip=Package Scope:Sorry,You can't log in!
succTip=Package Scope:welcome,you has logged in!

 lee 下 有:package_zh_CN.properties

failTip=包范围消息:对不起,您不能登录!
succTip=包范围消息:欢迎,您已经登录!
 

注意: 这 2 份资源文件保存在 WEB-INF/classes/lee 路径下,该资源文件就可以被位于 lee 包 及 lee 包下所有子包内的 Action 访问了

 

结论: Action 将优先使用包范围的资源文件 ,虽然也提供了全局范围的资源文件,但是 Action 优先使用包范围的资源文件

 

 

3.2  Action 范围资源文件

 

Struts 2 还允许为 Action 单独指定一份国际化资源文件。

 

Action 单独指定国际化资源文件的方法 是:

Action 文件所在的路径建立多个文件名为 ActionName_language_country.properties 的文件,一旦建立了这个系列的国际化资源文件Action 将可以访问该 Action 范围的资源文件。

 

还是使用前一节的 Action 类,该 Action 类的类文件位于 WEB-INF/classes/lee/action 路径下,于是我们建立如下 2 份资料文件

 

LoginAction_en_US.properties

failTip=Action Scope:Sorry,You can't log in!
succTip=Action Scope:welcome,you has logged in!

 LoginAction_zh_CN.properties

failTip=Action范围消息:对不起,您不能登录!
succTip=Action范围消息:欢迎,您已经登录!
 

一旦建立了这 2 份资源文件,lee.action.LoginAction 将优先加载 Action 范围的资源文件。

 

 

通过使用这种 Action 范围的资源文件,就可以在不同的 Action 里使用相同的 key 名来表示不同的字符串值 。例如,在 ActionOne 中 title 为 “动作一”,而同样用 title 在 ActionTwo 中则可以表示 “动作二” ,这样就可以简化 key 的命名,无需像 Struts 1 中使用 loginForm.title、registForm.title 来以示区分了。

 

提示: Action 范围的资源文件和包范围的资源文件同时存在时,系统将优先使用 Action 范围的资源文件

 

 

 

3.3  临时指定资源文件

 

临时指定资源文件的方式: 可以在 JSP 页面中输出国际化消息时临时指定国际化资源的位置。

在这种方式下,需要借助 Struts 2 的另外一个标签:<s:i18n .../>

 

如果把 <s:i18n .../> 标签作为 <s:text .../> 标签的父标签,则 <s:text .../> 标签将会直接加载 <s:i18n .../> 标签里指定的国际化资源文件;如果把 <s:i18n .../> 标签当成表单标签的父标签,则表单标签的 key 属性将会从国际化资源文件中加载该消息。

 

 

WEB-INF/classes 路径下,假设包含如下 2 份资源文件:

tmp_zh_CN.properties

#在JSP页面使用的临时资源文件
loginPage=临时消息:登录页面
errorPage=临时消息:错误页面
succPage=临时消息:成功页面
failTip=临时消息:全局消息:对不起,您不能登录!
succTip=临时消息:全局消息:欢迎,您已经登录!
user=临时消息:用户名
pass=临时消息:密  码
login=临时消息:登录
 

tmp_en_US.properties

#在JSP页面临时使用的资源文件
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

<%@ 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>
	<title>
	<s:i18n name="tmp">
		<s:text name="loginPage"/>
	</s:i18n>
	</title>
	<meta name="website" content="http://www.crazyit.org" />
</head>
<body>
<!-- 使用i18n作为s:text标签的父标签,临时指定国际化资源文件的baseName为tmp -->
<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>
</body>
</html>
 

 

3.4  加载资源文件的顺序

 

Struts 2 提供了如此多的方式来加载国际化资源文件,这些加载国际化资源文件的方式有自己的优先顺序。假设需要在 ChildAction 中访问国际化消息,则系统加载国际化资源文件的优先级 是:

 

  ①  优先加载系统中保存在 ChildAction 的类文件相同位置,且 baseName ChildAction 的系列资源文件。

  ②  如果在 中找不到指定 key 对应的消息,且 ChildAction 有父类 ParentAction ,则加载系统中保存在 ParentAction 的类文件相同位置,且 baseName ParentAction 的系列资源文件。

  ③  如果在 中找不到指定 key 对应的消息,且 ChildAction 有实现接口 IChildAction ,则加载系统中保存在 IChildAction 的类文件相同位置,且 baseName IChildAction 的系列资源文件。

  ④  如果在 中找不到指定 key 对应的消息,且 ChildAction 有实现接口 ModelDriven (即使用模型驱动模式),则对于 getModel() 方法返回的 model 对象,重新执行第 操作。

  ⑤   如果在 中找不到指定 key 对应的消息,则查找当前包下 baseName package 的系列资源文件。

  ⑥  如果在 中找不到指定 key 对应的消息,则沿着当前包上溯,直到最顶层包来查找 baseName package 的系列资源文件。

  ⑦  如果在 中找不到指定 key 对应的消息,则查找 struts.custom.i18n.resources 常量指定 baseName 的系列资源文件。

  ⑧  如果经过上面步骤一直找不到该 key 对应的消息,将直接输出该 key 的字符串值;如果在上面的步骤 ~ 的任一步中,找到指定 key 对应的消息,系统将停止搜索,直接输出该 key 对应的消息

 

 

对于在 JSP 中访问国际化消息,则简单得多,分成 2 种形式

●  对于使用 <s:i18n .../> 标签作为父标签的 <s:text .../> 标签、表单标签的形式:

  将从 <s:i18n .../> 标签指定的国际化资源文件中加载指定 key 对应的消息。

  如果在 中找不到指定 key 对应的消息,则查找 struts.custom.i18n.resources 常量指定 baseName 的系列资源文件

  如果经过上面步骤一直找不到该 key 对应的消息,将直接输出该 key 的字符串值;如果在上面的步骤 ①~② 的任一步中,找到指定 key 对应的消息,系统停止搜索,直接输出该 key 对应的消息。


●  如果 <s:text .../> 标签、表单标签没有使用 <s:i18n.../> 标签作为父标签:

   直接加载 struts.custom.i18n.resources 常量指定 baseName 的系列资源文件。如果找不到该 key 对应的消息,将直接输出该 key 的字符串值;否则,则输出该 key 对应的国际化消息。

 

 

四、允许用户自行选择程序语言

 

    在很多成熟的商业软件中,可以让用户自由切换语言,当用户进入系统时,可以出现一个下拉列表框,让用户选择语言。

    struts 2 也可以允许用户自行选择语言。而且 更加简单!

 

4.1  Struts 2 国际化的运行机制

 

  Struts 2 中,通过 ActionContext.getContext().setLocale(Locale arg) 设置用户的默认语言,不过这种方式完全是一种手动方式,而且需要编程实现。

 

为了简化设置用户默认语言环境, Struts 2 提供了一个名为 i18n 的拦截器Interceptor ),并将其注册在默认的拦截器栈中(defaultStack

 

struts2-core-2.2.1.jar struts-default.xml 中有如下片段:

<interceptor-stack name="defaultStack">
                <interceptor-ref name="exception"/>
                <interceptor-ref name="alias"/>
                <interceptor-ref name="servletConfig"/>
                <interceptor-ref name="i18n"/>
                <interceptor-ref name="prepare"/>
                <interceptor-ref name="chain"/>
                <interceptor-ref name="debugging"/>
                <interceptor-ref name="scopedModelDriven"/>
                <interceptor-ref name="modelDriven"/>
                <interceptor-ref name="fileUpload"/>
                <interceptor-ref name="checkbox"/>
                <interceptor-ref name="multiselect"/>
                <interceptor-ref name="staticParams"/>
                <interceptor-ref name="actionMappingParams"/>
                <interceptor-ref name="params">
                  <param name="excludeParams">dojo\..*,^struts\..*</param>
                </interceptor-ref>
                <interceptor-ref name="conversionError"/>
                <interceptor-ref name="validation">
                    <param name="excludeMethods">input,back,cancel,browse</param>
                </interceptor-ref>
                <interceptor-ref name="workflow">
                    <param name="excludeMethods">input,back,cancel,browse</param>
                </interceptor-ref>
            </interceptor-stack>
 

 ★   i18n 拦截器在执行 Action 方法前,自动查找请求中一个名为 request_locale 的参数。如果该参数存在,拦截器就将其作为参数转换成 Locale 对象,并将其设为用户默认的 Locale

   除此之外,i18n 拦截器还会将上面生成的 Locale 对象保存在用户 Session 的名为 "WW_TRANS_I18N_LOCALE " 属性中。一旦用户 Session 中存在 "WW_TRANS_I18N_LOCALE " 属性,该属性指定的 Locale 会作为浏览者的默认 Locale

 

 

4.2  创建下拉列表框、选择程序语言

 

   实现用户自行选择程序语言功能,只需提供一个下拉框列表,并且当用户选择下拉框中某一项时,系统将该下拉项的值作为 request _locale 参数提交给 Struts 2 .

 

定义一个 javabean 保存系统支持的全部语言:

Locales.java

import java.util.*;

//该JavaBean存放了系统所支持的全部语言
public class Locales {
    // 使用current保存用户当前选择的Locale
    private Locale current;

    public void setCurrent(Locale cur) {
        this.current = cur;
    }

    // 取得本系统所支持的全部语言
    public Map<String, Locale> getLocales() {
        // 将当前系统支持的全部语言保持在Map对象中
        Map<String, Locale> locales = new Hashtable<String, Locale>();
        ResourceBundle bundle = ResourceBundle.getBundle("messageResource",
            current);
        // 添加当前系统支持的语言,key是系统支持语言的显示名字,
        // value是系统支持语言的Locale实例
        locales.put(bundle.getString("enus"), Locale.US);
        locales.put(bundle.getString("zhcn"), Locale.CHINA);
        return locales;
    }
}
 

上述,Map 的 key 是所支持语言的显示名字,value 是所支持语言的 Locale 实例

 


selectlanguage.jsp

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<%@taglib prefix="s" uri="/struts-tags"%>
<script type="text/javascript">
function langSelecter_onChanged()
{
	document.getElementById("langForm").submit();
}
</script>

<!-- 将HTTP Session中的"WW_TRANS_I18N_LOCALE"
	属性值设置成SESSION_LOCALE -->
<s:set name="SESSION_LOCALE" value="#session['WW_TRANS_I18N_LOCALE']"/>

<!-- 使用lee.Locales创建locales实例 -->
<s:bean id="locales" name="lee.Locales">
	<!-- 为locales实例传入current参数值 -->
	<s:param name="current" 
		value="#SESSION_LOCALE == null ? locale : #SESSION_LOCALE"/>
</s:bean>

<form action="<s:url/>" id="langForm" 
    style="background-color:#bbbbbb; padding-top: 4px; padding-bottom: 4px;">
    
    <s:text name="language"/>
	<s:select label="Language" list="#locales.locales" 
		listKey="value" listValue="key"
        value="#SESSION_LOCALE == null ? locale : #SESSION_LOCALE"
        name="request_locale" id="langSelecter" 
        onchange="langSelecter_onChanged()" theme="simple"/>
</form>
 

注意: 使用 <s:set .../> 将用户 Session 的 " WW_TRANS_I18N_LOCALE " 属性值设置成 SESSION_LOCALE ,并创建了 lee.Locales 类的 locales 实例,并为该实例传入 current 参数值,先判断 SESSION_LOCALE 是否为 null ,如果为 null   则返回 ValueStack 中的 locale 属性值(即用户浏览器设置的 Locale );如果不为 null ,则返回  SESSION_LOCALE 的值(即用户选择的 Locale

 

 

messageResource_en_US.properties

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

language=Select Lanuage
enus=American English
zhcn=Simplified Chinese
 

messageResource_zh_CN.properties

loginPage=登陆页面
errorPage=错误页面
succPage=成功页面
failTip=对不起,您不能登录!
succTip=欢迎,您已经登录!
user=用户名
pass=密  码
login=登陆

language=选择语言
enus=美式英语
zhcn=简体中文
 

本例 JSP 都放在 WEB-INF/jsp 下,从而避免直接访问 JSP 页面,让所有 JSP 页面都能得到  Struts 2 处理

 

struts.xml

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
	"-//Apache Software Foundation//DTD Struts Configuration 2.1//EN"
	"http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
	<constant name="struts.custom.i18n.resources"
		value="messageResource"/>
	<constant name="struts.i18n.encoding" value="GBK"/>

	<package name="lee" extends="struts-default">
		<action name="login" class="lee.LoginAction">
			<result name="error">/WEB-INF/jsp/error.jsp</result>
			<result name="success">/WEB-INF/jsp/welcome.jsp</result>
		</action>
		<action name="*">
			<result>/WEB-INF/jsp/{1}.jsp</result>
		</action>
		<action name="">
			<result>.</result>
		</action>
	</package>
</struts>

 

 

<action name="*">
        <result>/WEB-INF/jsp/{1}.jsp</result>
 </action>

 上面代码 请求 selectlanguage.action

 

login.jsp

<%@ 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>
	<title><s:text name="loginPage"/></title>
</head>
<body>
<s:include value="selectlanguage.jsp"/>
<s:form action="login">
	<s:textfield name="username" key="user"/>
	<s:textfield name="password" key="pass"/>
	<s:submit key="login"/>
</s:form>
</body>
</html>
 

通过如下标签来选择语言

<s:include value="selectlanguage.jsp"/>

 

成功和失败 jsp

welcome.jsp

<%@ 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>
	<title><s:text name="succPage"/></title>
</head>
<body>
	${requestScope.tip}
</body>
</html>
 

error.jsp

<%@ 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>
	<title><s:text name="errorPage"/></title>
</head>
<body>
	${requestScope.tip}
</body>
</html>
 

原理 : 用户选择了语言后,系统将用户选择设置成了 HTTP Session 的 "WW_TRANS_I18N_LOCALE "  属性值,该 Session 属性值直接决定 Struts 2 系统的语言环境。

 

 

 

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    struts2国际化例子源码

    在Struts2中实现国际化,可以帮助开发者创建对多语言环境友好的应用。 本示例主要围绕Struts2框架如何实现国际化进行深入探讨。源码中包含两个关键部分:WebRoot目录和src目录。 1. **WebRoot** 目录: - `WEB-...

    Struts2国际化的实现原理

    Struts2国际化的实现原理;简单的struts2国际化实现过程的讲解

    struts2国际化 标签 页面 处理类

    Struts2是一个流行的Java web框架,它提供了强大的国际化支持,帮助开发者创建多语言的应用程序。在Struts2中实现国际化,主要包括配置、JSP页面、表单和Action类的处理。 首先,在`struts.xml`配置文件中,我们...

    Struts2国际化Demo

    在“Struts2国际化Demo”中,我们主要探讨的是如何利用Struts2框架实现应用的多语言支持,即国际化(i18n)功能。国际化是一种设计方法,使得软件能够根据不同地区的语言和文化习惯进行调整,使得全球用户都能无障碍...

    STRUTS2国际化的问题

    ### STRUTS2国际化的问题 #### 一、Struts2国际化的概述 Struts2作为一个流行的Web应用框架,为了满足全球用户的使用需求,提供了一系列国际化(Internationalization, 简称I18N)的支持。这包括了如何在配置文件...

    struts2国际化MyEclipse开发

    struts2国际化MyEclipse开发struts2国际化MyEclipse开发童叟无欺

    struts2国际化源码以及eclipse国际化插件

    在Struts2中实现国际化(i18n)是一项重要功能,它允许应用程序支持多种语言,以满足全球用户的需求。国际化不仅仅是翻译文本,而是设计应用程序以适应不同地区的文化习惯和语言需求。 首先,让我们来探讨一下...

    struts1.2 国际化

    #### 二、本地化与国际化基础 ##### 1. 本地化 (Localization) 本地化是指将软件产品调整以适应某个特定市场(国家/地区或语言)的过程。这通常涉及将界面文字、日期和时间格式、货币单位以及其他文化相关的元素...

    struts2国际化测试

    在“struts2国际化测试”这个主题中,我们将探讨如何在Struts2框架下实现应用程序的国际化功能。 首先,国际化(i18n,i代表第9个字母n,18是n到i的字母数,表示国际化)是使软件能够适应不同语言和文化背景的重要...

    Struts1 和 Struts 2 国际化全局资源

    Struts1 和 Struts 2 是两种非常流行的Java Web开发框架,它们都提供了对国际化(i18n)的支持,使得应用能够根据用户的语言和地区显示相应的本地化内容。国际化是软件设计的一个重要方面,它允许应用程序在全球范围...

    struts2国际化处理全解

    在国际化处理方面,Struts2提供了全面的支持,使得开发者能够轻松地为多语言环境的应用程序创建接口。 首先,我们需要了解什么是国际化(Internationalization)和本地化(Localization)。国际化是指设计和开发...

    struts2标签库及国际化的使用例子

    二、Struts2 国际化功能 Struts2 框架提供了强大的国际化功能,用于支持多语言显示。在本实验中,我们将使用 Struts2 的国际化功能来实现用户注册页面的国际化显示。 首先,我们需要创建国际化资源文件,例如 `...

    Struts2国际化支持引导(初)

    这篇指南将深入探讨Struts2如何实现国际化支持,并提供一个初步的引导。 首先,理解国际化的基本概念是至关重要的。国际化不仅仅是翻译文本,它还涉及到日期、时间、货币等格式的本地化。在Java中,这一过程通常...

    struts2国际化+简单的标签+用户注册和登录

    总的来说,这个项目提供了一个基础的Struts2应用实例,展示了如何实现国际化、使用Struts2标签库,以及创建简单的用户注册和登录功能,尽管它并不涉及实际的数据存储。对于学习和理解Struts2框架的运作机制,这是一...

    Struts2 使用 Struts2 实现国际化

    **二、Struts2国际化配置** 1. **创建资源文件**: 在Struts2中,我们通常创建名为`Messages.properties`的主资源文件,用于存储默认语言(通常是英语)的字符串。对于其他语言,如法语,可以创建`Messages_fr....

    struts2国际化demo

    "Struts2国际化demo"是一个示例,展示了如何在Struts2框架下实现这一功能,使得网站可以根据用户的浏览器设置显示不同的语言。 首先,要实现国际化,我们需要创建资源文件。在Java中,这些通常是`.properties`文件...

    struts2 国际化使用

    在Struts2中实现国际化,可以帮助你的应用触达全球用户。 Struts2的国际化主要依赖于Java的ResourceBundle类,该类用于管理应用程序中的多语言资源。以下是如何在Struts2中进行国际化设置的详细步骤: 1. **创建...

    struts2框架国际化

    国际化(i18n)是Struts2的一个重要特性,使得应用能够支持多种语言环境,以满足全球用户的语言需求。以下是对Struts2框架国际化实现的详细讲解。 1. **国际化的基本概念** 国际化(Internationalization,简称i18...

    Struts2国际化(可选择语言)

    在Struts2中实现国际化(I18n,Internationalization)是常见的需求,目的是使应用程序能够根据用户的语言和地区提供相应的本地化内容。本示例将详细介绍如何在Struts2框架下实现国际化,并通过myEclipse开发环境...

Global site tag (gtag.js) - Google Analytics