J2EE-网页语言切换之国际化i18n

qsuron 发布于 2014-08-28 Java 36 次阅读 3 条评论 1779 字 预计阅读时间: 8 分钟


最近在项目中,需要去做一个页面的中英文切换,因此用到了struts自带的国际化 i18n 包,由于我所在的项目是 struts 1.x ,但是网上大多都是 struts 2 因此我把两个都一起记录下来了,基本的操作是一样的。

i18n其来源是英文单词 internationalization 的首末字符i和n,18为中间的字符数)是“国际化”的简称。在资讯领域,国际化(i18n)指让产品(出版物,软件,硬件等)无需做大的改变就能够适应不同的语言和地区的需要。对程序来说,在不修改内部代码的情况下,能根据不同语言及地区显示相应的界面。 在全球化的时代,国际化尤为重要,因为产品的潜在用户可能来自世界的各个角落。

一,struts 1.x

1,基本的国际化

步骤1:配置struts国际化

在struts-config.xml中配置message-resources标签

<message-resource parameter="MessageResource"/>

其中的参数是国际化配置文件MessageResource.properties的文件名。

步骤2:提供国际化配置文件

中文:MessageResource_zh_cn.properties

英文:MessageResource_en_us.properties

源文件:resource.properties表示中文信息

在源文件resource.properties中硬编码中文信息
user.title=用户登录
user.username=用户
user.password=密码
user.button.login=登录

然后用java中提供的工具把这些信息转换为unicode放到相应国际化文件中。

MessageResource_zh_cn.properties文件中

user.title=\u7528\u6237\u767b\u5f55
user.username=\u7528\u6237
user.password=\u5bc6\u7801
user.button.login=\u767b\u5f55

MessageResource_en_us.properties文件中

user.title=User Login
user.username=User Name
user.password=Password
user.button.login=Login

步骤3:在jsp页面上用struts标签<bean:message>来读取国际化消息文本

引入标签:

<%@ taglib prefix="bean" uri="http://struts.apache.org/tags-bean"%

<form action="login.do" method="post">
  <bean:message key="user.username"/>:<input type="text" name="username"><br>
  <bean:message key="user.password"/>:<input type="password" name="password"><br>
  <input type="submit" value="<bean:message key="user.button.login"/>">
 </form>

bean:message中的属性key指的是国际化文件中的键。

一个local对应一个session

二,国际化的切换

jsp页面:

  <a href="changelang.do?lang=zh">中文</a>&nbsp&nbsp&nbsp<a href="changelang.do?lang=en">英文</a>

添加一个Action:

public ActionForward execute(ActionMapping mapping, ActionForm form,
   HttpServletRequest request, HttpServletResponse response)
   throws Exception {
  String lang = request.getParameter("lang");
  

//得到Locale
  Locale currentLocale = Locale.getDefault();
  if ("zh".equals(lang)) {

       //自定义Locale
   currentLocale = new Locale("zh", "CN");
  }else if("en".equals(lang)) {
   currentLocale = new Locale("en", "US");
  }

  //自己设置Locale
  //request.getSession().setAttribute(Globals.LOCALE_KEY, currentLocale);
  //调用struts中提供的方法设置Locale
  this.setLocale(request, currentLocale);
  return mapping.findForward("index");
 }

 配置国际化action:

<action path="/changelang"
    type="com.bjsxt.struts.ChangeLanguageAction"
  >
   <forward name="index" path="/index.jsp"/>
  </action>

 <message-resources parameter="res.MessageResources" />

res.MessageResources表示的是res包下的MessageResources文件。

三,动态信息的国际化

如果是与后台交互的数据,那么在国际化文件中就用占位符进行配置

resource.properties源文件:

user.login.success={0},登录成功
user.not.found=用户不能找到,用户名称=[{0}]
user.password.error=密码错误
user.login.error=登录失败

MessageResource_zh_cn.properties文件:

user.login.success={0},\u767b\u5f55\u6210\u529f
user.not.found=\u7528\u6237\u4e0d\u80fd\u627e\u5230\uff0c\u7528\u6237\u540d\u79f0=[{0}]
user.password.error=\u5bc6\u7801\u9519\u8bef
user.login.error=\u767b\u5f55\u5931\u8d25MessageResource_en_us.properties文件:

user.login.success={0},Login Success
user.not.found=User Not Found,UserName[{0}]
user.password.error=Password Error
user.login.error=Login Error

Action中的代码:

package com.bjsxt.struts;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;

/**  
 * 用户登录的Action
 * @author Administrator
 *
 */
public class LoginAction extends Action {
 
 public ActionForward execute(ActionMapping mapping, ActionForm form,
   HttpServletRequest request, HttpServletResponse response)
   throws Exception {
  LoginActionForm laf = (LoginActionForm)form;
  String username = laf.getUsername();
  String password = laf.getPassword();

  ActionMessages messages = new ActionMessages();
  try {
   UserManager.getInstance().login(username, password);
   
   //创建国际化消息文本
   ActionMessage message = new ActionMessage("user.login.success", username);
   //ActionMessage message = new ActionMessage("user.login.success", new Object[]{username});//其中Object数组表示的是占位符
   messages.add("loginSuccess1", message);

   ActionMessage message1 = new ActionMessage("user.login.success", username);
   messages.add("loginSuccess2", message1);
   
   //传递国际化消息文本
   this.saveMessages(request, messages);
   return mapping.findForward("success");
  }catch(UserNotFoundException unfe) {
   unfe.printStackTrace();
   
   //创建国际化消息文本
   ActionMessage message = new ActionMessage("user.not.found", username);
   messages.add("error1", message);
   
   //传递国际化消息文本
   this.saveErrors(request, messages);
  }catch(PasswordErrorException pee) {
   pee.printStackTrace();
   //创建国际化消息文本
   ActionMessage message = new ActionMessage("user.password.error");
   messages.add("error2", message);
   
   //传递国际化消息文本
   this.saveErrors(request, messages);
  }
  return mapping.findForward("error");
 }

}

一个ActionMessage表示一条国际化信息。

Action配置:

<message-resources parameter="res.MessageResources" />

 

 

二,struts 2

 

1.首先在struts.properties文件中加入以下内容:

struts.custom.i18n.resources=messageResource
或在struts.xml中加入
<constant name="struts.custom.i18n.resources" value="messageResource"></constant>

 

2.资源文件的命名格式:

名称_语言代码_国家代码. Properties
如果创建中文和英语国际化,那么资源文件名称为
messageResource_zh_CN.properties和messageResource_en_US.properties

 

3. jsp页面的国际化

 
通过使用标签<s:text name="label.helloWorld"/>输出国际化
label.helloWorld为资源文件中定义的key

 

在messageResource_en_US.properties加入以下内容
label.hello=hello {0}
label.helloWorld=hello,world

在messageResource_zh_CN.properties加入以下内容
label.hello=你好 {0}
label.helloWorld=你好,世界

 

(1). <s:text name="label.helloWorld"/>
<s:property value="%{getText('label.helloWorld')}"/>
上面两个都为输出一个hello word的两种表示

 

<s:textfield name="name" key="label.helloWorld"/>
<s:textfield name="name" label="%{getText('label.helloWorld')}"/>
显示一个文本框,文本框的标题进行国际化

 

(2). 使用<s:i18n>标签指定从某个特定的资源文件中取数据
<s:i18n name="messageResource">
   <s:text name="label.helloWorld"></s:text>
</s:i18n>
指定在从messageResource取资源

 

(3).
<s:text name="label.hello">
   <s:param>callan</s:param>
</s:text>
使用带参数的资源.<s:param>可以替换label.hello=hello {0}中的{0}

 

4. Action的国际化

Action的国际化主要是通过getText(String key)方法实现的

String str1 = getText("label.helloWorld"); 

5. 参数化国际化

在messageResource_en_US.properties加入以下内容
userName=userName
userName.required=${getText('userName')} is required

 

在messageResource_zh_CN.properties加入以下内容
userName=用户名
userName.required=${getText('userName')} 不能为空

 

在Action中
String str4 = getText("userName.required");
System.out.println(str4);

 

userName.required=${getText('userName')}会取国际化的用户名

 

6. 使用校验框价时,提示信息可以国际化

   <field name="userName">
   <field-validator type="requiredstring">
    <message key=”userName.required”> </message>
   </field-validator>
</field>

 

三,项目解决方案:

 由于老板的需求,是要在配置文件里面进行单一性质的修改,所以我的解决方案如下:

修改struts配置文件web.xml
添加/WEB-INF/language.xml分支

/WEB-INF/language.xml设置要读取的字库

读取
config/Language_Chinese.properties
config/Language_English.properties

JSP页面

包含struts-lib
<%@ taglib prefix="bean" uri="http://struts.apache.org/tags-bean"%>

使用标签
<bean:message key="hello"/>

切换语言方法:找到 WEB_INF/language.xml 按照注释内容进行修改

代码敲的累了,换个中文悠闲悠闲。
最后更新于 2025-05-24