关于Struts2的国际化问题

在做项目时,遇到了点击首页两个链接实现系统全部国际化的问题。以下两篇文章帮助很大,故摘录下来:

第一篇文章: http://whp0731.iteye.com/blog/417222


Jsp代码
<body>
<s:a href="/Struts2/changeLang.action?lang=en">English</s:a>
<s:a href="/Struts2/changeLang.action?lang=zh">中文</s:a>
<center>
<s:text name="addUser"/>
</center>
</body>
Jsp代码
<body>
<s:a href="/Struts2/changeLang.action?lang=en">English</s:a>
<s:a href="/Struts2/changeLang.action?lang=zh">中文</s:a>
<center>
<s:text name="addUser"/>
</center>
</body>

struts.xml
Xml代码
<struts>
<!-- 设置全局配置文件 -->
<constant name="struts.custom.i18n.resources" value="message"/>
<!-- 解决中文乱码 -->
<constant name="struts.i18n.encoding" value="gbk"/>

<package name="Struts2" extends="struts-default">

<action name="changeLang" class="com.bjsxt.action.ChangeLangAction">
<result name="success">/register2/register.jsp</result>
</action>

</package>
</struts>
Xml代码
<struts>
<!-- 设置全局配置文件 -->
<constant name="struts.custom.i18n.resources" value="message"/>
<!-- 解决中文乱码 -->
<constant name="struts.i18n.encoding" value="gbk"/>

<package name="Struts2" extends="struts-default">

<action name="changeLang" class="com.bjsxt.action.ChangeLangAction">
<result name="success">/register2/register.jsp</result>
</action>

</package>
</struts>

message_en_US.properties
Properties代码
addUser=Add User
Properties代码
addUser=Add User

message_ zh _CN.properties
Properties代码
addUser=\u6DFB\u52A0\u7528\u6237
Properties代码
addUser=\u6DFB\u52A0\u7528\u6237


ChangeLangAction
Java代码
public class ChangeLangAction extends ActionSupport{
private String lang;

public String getLang() {
return lang;
}

public void setLang(String lang) {
this.lang = lang;
}

@Override
public String execute() throws Exception {
changeLang();
return SUCCESS;
}

/**
* 手动改变Locale
*/
private void changeLang() {
Locale currentLocale = Locale.getDefault();
//1、根据页面请求,创建下同的Locale对象
if("en".equals(getLang().trim())) {
currentLocale = new Locale("en","US");
}else if("zh".equals(getLang().trim())) {
currentLocale = new Locale("zh","CN");
}
/*
* 2、设置Action中的Locale
* 前台页面的Locale和后台session中的Locale范围是不一样的
* a)只改页面Locale当前页面信息会改变但提交后Locale又会改回到默认的
* b)改变了后台Locale,当前线程中的页面Locale并不会改变,但会随下一次提交
* Action一同改变,所以可能要刷新页面两次,第一次只变后台Locale,第二次
* 前台和后台同时改变
*
* 为避免上述情况,需要前台和后台的Locale一起改变
*/

ActionContext.getContext().setLocale(currentLocale);
ServletActionContext.getRequest().getSession().setAttribute(
"WW_TRANS_I18N_LOCALE", currentLocale);
}
}
Java代码
public class ChangeLangAction extends ActionSupport{
private String lang;

public String getLang() {
return lang;
}

public void setLang(String lang) {
this.lang = lang;
}

@Override
public String execute() throws Exception {
changeLang();
return SUCCESS;
}

/**
* 手动改变Locale
*/
private void changeLang() {
Locale currentLocale = Locale.getDefault();
//1、根据页面请求,创建下同的Locale对象
if("en".equals(getLang().trim())) {
currentLocale = new Locale("en","US");
}else if("zh".equals(getLang().trim())) {
currentLocale = new Locale("zh","CN");
}
/*
* 2、设置Action中的Locale
* 前台页面的Locale和后台session中的Locale范围是不一样的
* a)只改页面Locale当前页面信息会改变但提交后Locale又会改回到默认的
* b)改变了后台Locale,当前线程中的页面Locale并不会改变,但会随下一次提交
* Action一同改变,所以可能要刷新页面两次,第一次只变后台Locale,第二次
* 前台和后台同时改变
*
* 为避免上述情况,需要前台和后台的Locale一起改变
*/

ActionContext.getContext().setLocale(currentLocale);
ServletActionContext.getRequest().getSession().setAttribute(
"WW_TRANS_I18N_LOCALE", currentLocale);
}
}


看提供的例子很重要:

运行例子struts2-blank-2.0.9
http://localhost:8080/struts2-blank-2.0.9/example/HelloWorld.action?request_locale=en有效。

原来在Struts 2.0中,通过ActionContext.getContext().setLocale(Locale arg)可以设置用户的默认语言。
Struts 2.0为您提供了一个名i18n的拦截器(Interceptor),并在默认情况下将其注册到拦截器链(Interceptor chain)中。
它的原理为在执行Action方法前,i18n拦截器查找请求中的一个名为"request_locale"的参数。
如果其存在,拦截器就将其作为参数实例化Locale对象,并将其设为用户默认的区域(Locale),最后,将此Locale对象保存在session的名为“WW_TRANS_I18N_LOCALE”的属性中。

除此之外,i18n拦截器还会将上面生成的Locale对象保存在用户Session的名为WW_TRANS_I18N_LOCALE的属性中。一旦用户Session中存在一个名为

WW_TRANS_I18N_LOCALE的属性,则该属性指定的Locale将会作为浏览者的默认Locale。

Struts1.X 与 Struts2.X 的区别 :

1、Struts1.X 通过在HttpSession中设置固定的变量实现

2、Struts2.X 比较方便,只需设置Action中的Locale

第二篇文章: http://blog.csdn.net/dahu1128/archive/2010/12/24/6096397.aspx

前台jsp:【1】

<head>
<title><s:text name="title"/></title>
<link href="css/index.css" type="text/css" rel="stylesheet" />
<link href="css/front.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="js/front.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>

<div style="float:left; margin-right:20px;"><a href="/cms/jingce/i18n/SelectLanguage.action?request_locale=zh_CN" ><s:text name="chinese"/></a></div>

<div style="float:left; margin-right:20px;"><a href="/cms/jingce/i18n/SelectLanguage.action?request_locale=en_US" ><s:text name="english"/></a></div>

struts.xml:【2】

<package name="article.front.inde2" namespace="/jingce/i18n" extends="struts-default">
<action name="SelectLanguage" method="selectLanguage" class="language.choose">
<result name="success" type="dispatcher">/jingce/index.jsp</result>
</action>
</package>

项目名:cms

目录结构:

按照如上的代码和配置将会产生的问题是: action能正常访问,也能正常跳转,也能正常国际化。但是跳转后页面将会变型,也就是说页面所引用的css与js以及页面内的图片地址将会找不到。

解决办法1:在jsp的head中添加如下js

<head>
<title><s:text name="title"/></title>
<link href="css/index.css" type="text/css" rel="stylesheet" />
<link href="css/front.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="js/front.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<script type="text/javascript">
function languageChoose(language){
var lan='/cms/jingce/i18n/SelectLanguage.action?request_locale='+language;
window.location.href=lan;
}
</script>
</head>

<div style="float:left; margin-right:20px;"><a href="#" onclick="languageChoose('zh_CN')"><s:text name="chinese"/></a></div>
<div style="float:left; margin-right:20px;"><a href="#" onclick="languageChoose('en_US')"><s:text name="english"/></a></div>

解决办法2

在所有相对路径前加入:<%=bastPath%>jingce/

例如:<%=bastPath%>jingce/css/index.css

解决办法3

<div style="float:left; margin-right:20px;"><a href="/cms/jingce/SelectLanguage.action?request_locale=zh_CN" ><s:text name="chinese"/></a></div>

<div style="float:left; margin-right:20px;"><a href="/cms/jingce/SelectLanguage.action?request_locale=en_US" ><s:text name="english"/></a></div>

<package name="article.front.inde2" namespace="/jingce" extends="struts-default">
<action name="SelectLanguage" method="selectLanguage" class="language.choose">
<result name="success" type="dispatcher">/jingce/index.jsp</result>
</action>
</package>

问题思考:

解决办法1相当于重新刷新页面,解决办法2很明显灵活性不强,如果目录改动岂不要修改所有地址,个人最喜欢解决办法3。

但是为什么会出现这种情况呢,对比跳转前与跳转后的图片地址。

跳转前:http://localhost:8080/cms/jingce/img/gywm.gif

跳转后:http://localhost:8080/cms/jingce/i18n/img/gywm.gif

action时Url地址:http://localhost:8080/cms/jingce/i18n/SelectLanguage.action?request_locale=en_US

之所以经过action后(我的action返回的是当前页面)图片和css的引用地址找不到,我推测是因为action跳转后容器将去掉action后剩下的地址作为当前的目录地址也就是:http://localhost:8080/cms/jingce/i18n/http://localhost:8080/cms/jingce/i18n/ 变成了当前目录,然项目中并无当前目录更不会在其中有img目录和该目录下的图片与其它资源文件了。

但是为什么还能跳转到正常页面呢?这是因为我强行指定了跳转后的页面地址:

<result name="success" type="dispatcher">/jingce/index.jsp</result>

如果我的推测是对的那么我将结果地址改成

<result name="success" type="dispatcher">index.jsp</result>
应该也能跳转到正常页面和正常显示样式,结果一试果然如此。
 

猜你喜欢

转载自wutheringsea.iteye.com/blog/1046311