`
hdxiong
  • 浏览: 378146 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Struts2 国际化

    博客分类:
  • SSH
阅读更多

Struts2中允许用户自行选择程序语言

最近在学习struts2,学习资料是李刚著的《struts2权威指南》,这本书写得非常好,非常有学习价值。我在学习过程中,自己跟着做了些例子。下面就是关于在struts2中允许用户自行选择程序语言的原理和示例:

在很多成熟的商业软件中,可以让用户自由切换语言,当用户进入系统时候,可以出现一个下拉列表框,让用户选择语言,一旦用户选择了自己需要使用的语言环境,整个系统的语言环境将一直是这种语言环境。
Struts2也可以允许用户自行选择程序语言。而且,因为Struts2的支持,在程序中自行选择语言环境将变得更加简单。

一. Struts2国际化的运行机制
在Struts 2中,我们可以通过ActionContext.getContext().setLocale(Locale arg)可以设置用户的默认语言。不过,这种方式完全是一种手动方式,而且需要编程实现。
为了简化设置用户默认语言环境,Struts 2提供了一个名i18n的拦截器(Interceptor),并且将其住注册在默认的拦截器栈中(defaultStack)。下面是Struts2的默认拦截器栈的配置片段,代码中粗体字表示的就是i18n的拦截器
<interceptor-stack name="defaultStack">
 <interceptor-ref name="exception"/>
 <interceptor-ref name="alias"/>
 <interceptor-ref name="servlet-config"/>
 <interceptor-ref name="prepare"/>
 <interceptor-ref name="i18n"/>
 <interceptor-ref name="chain"/>
 <interceptor-ref name="debugging"/>
 <interceptor-ref name="profiling"/>
 <interceptor-ref name="scoped-model-driven"/>
 <interceptor-ref name="model-driven"/>
 <interceptor-ref name="fileUpload"/>
 <interceptor-ref name="checkbox"/>
 <interceptor-ref name="static-params"/>
 <interceptor-ref name="params">
  <param name="excludeParams">dojo\..*</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。

二. 创建下拉列表框
基于前面的介绍,为了实现让用户自行选择程序语言的功能,只需提供一个下拉列表框,让下拉列表框中列出本应用所支持的各种语言,并且,当用户选择下拉列表框中某一项时,系统将该下拉项的值作为request_locale参数提交给Struts2系统,
为此,我们将系统所支持的语言放入一个Map中,通过在JSP页面中迭代该Map对象,通过这种方式,就可以在页面上列出系统所支持的全部语言,并让用户自由选择。
下面定义了JavaBean,这个JavaBean里保存了当前应用所支持的全部语言,该JavaBean的代码如下:
//该JavaBean存放了系统所支持的全部语言。
public class Locales
{
 //因为本实例也需要实现国际化,所以使用current作为用户当前的Locale
 private Locale current;
 //取得用户当前Locale的setter方法
 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("usen"), Locale.US);
         locales.put(bundle.getString("zhcn"), Locale.CHINA);
         return locales;
    }
}
在上面JavaBean中,我们使用了一个Map对象来保存所有用户支持的语言,该Map对象的key是所支持语言的显示名字,而该Map对象的value是所支持语言的Locale实例。应用支持语言的显示名字,也是通过国际化消息来生成的。
一旦定义了该JavaBean之后,就可以在JSP页面中创建该JavaBean的实例,并为其传入一个current参数,决定该JavaBean中的Locale参数,就可以根据该Locale参数来决定怎样显示系统所支持语言显示名称。
为了在JSP页面中使用该JavaBean实例,使用下面标签来创建该JavaBean实例。
<!-- 使用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>
上面标签创建了lee.Locales类的locales实例,并为该实例传入了current参数值,设置该参数值时使用了三目运算符,先判断SESSION_LOCALE是否为空,如果该SESSION_LOCALE为空,则返回ValueStack中locale属性值(即用户浏览器设置的Locale);如果SESSION_LOCALE不为空,则返回该SESSION_LOCALE的值(即用户选择的Locale)。
为了让该页面中包含SESSION_LOCALE,使用Struts2的<s:set .../>标签将用户Session中的“WW_TRANS_I18N_LOCALE”属性值设置成SESSION_LOCALE。
下面是完成该设置的标签:
<!-- 将用户Session中的“WW_TRANS_I18N_LOCALE”属性值设置成SESSION_LOCALE。 -->
<s:set name="SESSION_LOCALE" value="#session['WW_TRANS_I18N_LOCALE']"/>
下面是该selectlanguage.jsp页面的代码:
<%@taglib prefix="s" uri="/struts-tags"%>
<script type="text/javascript">
function langSelecter_onChanged()
{
 document.getElementById("langForm").submit();
}
</script>
<!-- 将用户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="languag"/>
 <!-- 使用s:select标签迭代locales实例的locales Map属性 -->
 <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>
注意:上面页面中大量使用了Struts2的标签,关于Struts2标签的详细用法,请参考本书第十章的讲解。
上面页面的原理是:使用<s:set .../>标签实例化一个Locales对象,并使用<s:select ..../>标前来显示该Locales对象的locales(Map类型)属性, <s:select ..../>可以使用一个下拉列表框来显示Map类型的集合,本应用将该Map的key输出成下拉列表项的显示名称,将该Map的value输出成下拉列表项的值。
除此之外,页面上面还有一段简单的Javascript脚本,它会在用户在选择下拉列表中某一项后,提交包含“reqeust_locale”变量的表单到Action。
上面页面和JavaBean一共使用了三个国际化key,所以需要在资源文件定义这三个key对应的国际化消息。因为本系统仅支持简体中文和美式英语两种环境(如需要增加其他语言也非常简单, 只需要增加更过的资源文件,并简单修改Locales类即可),所以需要分别在中文资源文件中增加如下三项:
languag=选择语言
usen=美式英语
zhcn=简体中文
在英文资源文件中增加如下三项:
languag=Select Lanuage
usen=American English
zhcn=Simplified Chinese

三. 选择程序语言
本应用为了更好的安全性,将所有的JSP页面都放在WEB-INF/jsp路径下,从而避免了直接访问JSP页面,为了让所有的JSP页面都能得到Struts2的处理,在struts.xml文件中增加如下配置片段:
<!-- 使用通配符号定义Action的name -->
<action name="*">
 <!-- 将请求转发该WEB-INF/jsp路径下同名的JSP页面 -->
<result>/WEB-INF/jsp/{1}.jsp</result>
</action>
如果在浏览器中请求selectlanguage.action,将看到选择程序语言的页面。
如果用户通过上面的下拉列表框选择了“美式英语”项后,将看到用户选择美式英语的页面。
一旦定义了上面的页面后,我们就可以在JSP页面中通过<s:include .../>标签来包含该页面,包含该页面后,就可以自行选择程序语言了。
例如在登陆页面中通过如下标签来包含上面选择程序语言的页面:
<!-- 包含让用户自行选择程序语言的页面 -->
<s:include value="selectlanguage.jsp"/>
在任何页面中增加了上面代码后,该页面就能允许用户自行选择语言。通常,我们只需要在应用的第一个页面让用户选择程序语言,后续页面直接使用该语言即可。
如果浏览者在浏览器的地址栏访问input.action,Struts2自动进入WEB-INF/jsp/input.jsp页面,将看到允许用户选择程序语言的页面。
如果用户希望使用美式英语的语言,则在允许用户选择程序语言的页面的下拉列表框中选中“美式英语”项,将看到使用美式英语界面的页面。
如果用户登陆成功,将看到美式英语环境下登陆成功的页面。该页面自动使用了美式英语的环境,这都是因为用户选择了美式英语的语言后,系统将用户选择设置成了Session的WW_TRANS_I18N_LOCALE属性值,该Session属性值直接决定Struts2系统的语言环境。

 

 

 

资源文件的命名:basename_language_country.properties

JAVA国际化

如果系统同时存在资源文件、类文件,系统将以类文件为主,而不会调用资源文件。

对于简体中文的Locale,ResourceBundle搜索资源的顺序是:

(1)baseName_zh_CN.class

(2)baseName_zh_CN.properties

(3)baseName_zh.class

(4)baseName_zh.properties

(5)baseName.class

(6)baseName.properties

 

Struts2的国际化入门

Struts2国际化是建立在Java国际化的基础上的,一样是通过提供不同国家/语言环境的消息资源,然后通过ResourceBundle

加载指定Locale对应的资源文件,再取得该资源文件中指定key对应的消息--整个过程与JAVA程序的国家化完全相同,只是

Struts2框架对JAVA程序国际化进行了进一步封装,从而简化了应用程序的国际化。

Struts2需要国际化的部分

类型转换:

数据校验:

验证框架xml配置文件的国际化:RegisterAction-validation.xml文件<message key="username.xml.invalid"/>

JSP页面的国际化:<s:text name="addUser"/>

Action的国际化:利用ActionSupport类提供的getText()方法.

Struts2中加载全局资源文件

struts.xml

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

struts.properties

struts.custom.i18n.resources=baseName

访问国际化消息

Struts2访问国际化消息主要有如下三种方式:

(1)JSP页面:<s:text name="key"/>

(2)Action类中:使用ActionSupport类的getText方法。

(3)表单元素的Label里:为表单元素指定一个key属性

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

Struts2中提供了如下两种方式来填充消息字符串中的占位符

(1)JSP页面,在<s:text.../>标签中使用多个<s:param.../>标签来填充消息中的占位符。

(2)Action中,在调用getText方法时使用getText(String aTextName,List args)或getText(String key, String[] args)方法来填充占位符。

除此之外,Struts2还提供了对占位符的一种替代方式,这种方式允许在国际化消息资源文件中使用表达式,对于这种方式,则可避免在使用国际化消息时还需要为占位符传入参数值。

如下在消息资源中使用表达式

succTip=${username}, 欢迎, 您已经登录!

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

加载资源文件的方式

(1)加载全局资源文件: <constant name="struts.custom.i18n.resources" value="baseName"/>

(2)包范围资源文件 :为Struts2指定包范围资源文件的方法是,在包的根路径下建立多个文件名为package_language_country.properties的文件,一旦建立了

    这个系列的国际化资源文件,应用中处于该包下的所有Action都可以访问该资源文件。需要注意的是上面的包范围资源文件的baseName就是package,

 不是Action所在的包名。

(3)Action范围资源文件:在Action类文件所在的路径建立多个文件名为ActionName_language_country.properties的文件。

(4)临时指定资源文件:<s:i18n.../>标签的name属性指定临时的国际化资源文件

加载资源文件的顺序

Action中加载资源文件,假设我们在某个ChildAction中调用了getText("user.title"),Struts 2.0的将会执行以下的操作:

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

(2)如果在(1)中找不到指定key对应的消息,且ChildAction有父类ParentAction,则加载系统中保存在ParentAction的类文件相同位置,且

   baseName为ParentAction的系列资源文件。

(3)如果在(2)中找不到指定key对应的消息,且ChildAction有实现接口IChildAction,则加载系统中保存在IChildAction的类文件相同位置,且

   baseName为IChildAction的系列资源文件。

(4)如果在(3)中找不到指定key对应的消息,且ChildAction有实现接口ModelDriven(即使用模型驱动模式),则对于getModel()方法返回的model对象,

   重新执行第(1)步操作。

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

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

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

(8)如果经过上面的步骤一直找不到key对应的消息,将直接输出该key的字符串值。

对于在JSP中访问国际化消息,则简单的多,他们又可以分为两种形式:

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

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

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

   c、如果经过上面步骤一直找不到该key对应的消息,将直接输出该key的字符串值。

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

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

 

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

Struts2国际化的运行机制

    在Struts2中,可以通过ActionContext.getContext().setLocale(Locale arg)设置用户的默认语言。

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

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

并将其设为用户默认的Locale(代表国家/语言环境)。

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

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

<%@ page language="java" contentType="text/html; charset=GBK"%>

<%@taglib prefix="s" uri="/struts-tags"%>

<script. type="text/javascript">

function langSelecter_onChanged()

{

 document.getElementById("langForm").submit();

}

</script>

<%-- 设置SESSION_LOCALE为用户session中的WW_TRANS_I18N_LOCALE属性值 --%>

<s:set name="SESSION_LOCALE" value="#session['WW_TRANS_I18N_LOCALE']"/>

<%-- 使用lee.Locales创建locales实例 --%>

<s:bean id="locales" name="lee.Locales">

 <%-- 为locales实例传入current参数值,如果SESSION_LOCALE为空,则返回ValueStack中locale属性值(即用户浏览器设置的Locale) --%>

 <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="languag"/>

 <s:select label="Language" list="#locales.locales" listKey="value" listValue="key"

        value="#SESSION_LOCALE == null ? locale : #SESSION_LOCALE"

        name="request_locale" id="langSelecter"

        nchange="langSelecter_onChanged()" theme="simple"/>

</form>

在其他页面中包含该页面:

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

在struts.xml文件中增加Action通配符的配置:

<?xml version="1.0" encoding="GBK"?>

<!DOCTYPE struts PUBLIC

        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

        "http://struts.apache.org/dtds/struts-2.0.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 -->

  <action name="*">

   <!-- 将请求转发给/WEB-INF/jsp/路径下同名的JSP页面 -->

   <result>/WEB-INF/jsp/{1}.jsp</result>

  </action>

    </package>

</struts>

分享到:
评论

相关推荐

    struts2国际化例子源码

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

    Struts2国际化Demo

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

    STRUTS2国际化的问题

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

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

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

    Struts2国际化的实现原理

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

    Struts2国际化

    ### Struts2国际化详解 #### 一、引言 随着全球化的不断推进,软件系统越来越多地需要支持多种语言和地区设置,以满足不同国家和地区用户的使用习惯。因此,国际化(Internationalization,简称i18n)成为了现代...

    STRUTS2国际化

    Struts2的国际化功能,简称i18n,允许应用程序根据用户的语言和地区提供相应的界面和信息,无需修改核心代码。这一特性使得软件更具有全球化的适应性,满足不同文化和语言背景的用户需求。 **5.1 Struts2国际化原理...

    struts2国际化

    Struts2提供了一个默认的国际化资源文件`struts2-i18n.properties`,其中包含了框架自身的提示信息。开发者可以根据需要覆盖这些默认值,或者为特定的语言创建自定义的资源文件。 4. **Action中的国际化** 在...

    struts2 国际化

    在Struts2中,实现国际化是一项重要的功能,使得开发者可以为全球用户提供符合他们本地习惯的界面。 首先,国际化的核心是资源文件,通常命名为`properties`格式,如`messages.properties`。这些文件存储了应用中的...

    Struts1 和 Struts 2 国际化全局资源

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

    struts2国际化 标签 页面 处理类

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

    struts2国际化测试

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

    struts2国际化MyEclipse开发

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

Global site tag (gtag.js) - Google Analytics