Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 341|回复: 0

[struts学习]学习Struts 2.0系列(4)

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-10-10 23:53:18 | 显示全部楼层 |阅读模式
    来自:
    http://www.blogjava.net/max/arcHive/2006/11/01/78536.HTML

    国际化是商业系统中不可或缺的一部分,所以无论您学习的是什么Web框架,它都是必须掌握的技能。     其实,Struts 1.x在此部分已经做得相当不错了。它极大地简化了我们程序员在做国际化时所需的工作,例如,如果您要输出一条国际化的信息,只需在代码包中加入FILE-NAME_xx_XX.properties(其中FILE-NAME为默认资源文件的文件名),然后在struts-config.xml中指明其路径,再在页面用<bean:message>标志输出即可。      不过,所谓“没有最好,只有更好”。Struts 2.0并没有在这部分止步,而是在原有的简单易用的基础上,将其做得更灵活、更强大。 国际化Hello World
      
       
       
         
       

       
       
      

    下面让我们看一个例子――HelloWorld。这个例子演示如何根据用户浏览器的设置输出相应的HelloWorld。

    在Eclipse创建工程配置开发和运行环境(如果对这个步骤有问题,可以参考我早前的文章《为Struts 2.0做好准备》)。

    在src文件夹中加入struts.properties文件,内容如下:


      
       struts.custom.i18n.resources
       =
       globalMessages

       
       
       

       
         
          
          
          Struts 2.0有两个配置文件,struts.xml和struts.properties都是放在WEB-INF/classes/下。
            
            struts.xml用于应用程序相关的配置
            struts.properties用于Struts 2.0的运行时(Runtime)的配置
            
          
         
       
       

       
    在src文件夹中加入globalMessages_en_US.properties文件,内容如下:


      
       HelloWorld
       =
       Hello World!
       
    在src文件夹中加入globalMessages_zh_CN.properties文件,内容如下:


      
       HelloWorld
       =你
       好,世界!
       
       
       
         
         
         在此想和大家分享一个不错的编写properties文件的Eclipse插件(plugin),有了它我们在编辑一些简体中文、繁体中文等Unicode文本时,就不必再使用native2ascii编码了。您可以通过Eclipse中的软件升级(Software Update)安装此插件,步骤如下:

          
           1、展开Eclipse的Help菜单,将鼠标移到Software Update子项,在出现的子菜单中点击Find and Install;
          
    2、在Install/Update对话框中选择Search for new features to install,点击Next;
          
    3、在Install对话框中点击New Remote Site;
          
    4、在New Update Site对话框的Name填入“PropEdit”或其它任意非空字符串,在URL中填入http://propedit.sourceforge.jp/eclipse/updates/;
          
    5、在Site to include to search列表中,除上一步加入的site外的其它选项去掉,点击Finsih;
          
    6、在弹出的Updates对话框中的Select the features to install列表中将所有结尾为“3.1.x”的选项去掉(适用于Eclipse 3.2版本的朋友);
          
    7、点击Finish关闭对话框;
          
    8、在下载后,同意安装,再按提示重启Eclipse,在工具条看到形似vi的按钮表示安装成功,插件可用。此时,Eclpise中所有properties文件的文件名前有绿色的P的图标作为标识。
          
         
       
       
    在WebContent文件夹下加入HelloWorl.jsp文件,内容如下:


      
       <%
       @ page  contentType
       =
       "
       text/html; charset=UTF-8
       "
       %>
       

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

       <
       html
       >
       

       <
       head
       >
       
         
       <
       title
       >
       Hello World
       </
       title
       >
       

       </
       head
       >
       

       <
       body
       >
       
         
       <
       h2
       ><
       s:text
       name
       ="HelloWorld"
       
       /></
       h2
       >
       
         
       <
       h2
       ><
       s:property
       value
       ="% { getText("HelloWorld")}"
       
       /></
       h2
       >
       

       </
       body
       >
       

       </
       html
       >
       
    发布运行应用程序,在浏览器地址栏中输入http://localhost:8080/Struts2_i18n/HelloWorld.jsp ,出现图1所示页面。



    图1 中文输出
    将浏览器的默认语言改为“英语(美国)”,刷新页面,出现图2所示页面。


    图2 英文输出  
    上面的例子的做法,与Struts 1.x的做法相似,似乎并不能体现Struts 2.0的优势。不过,我在上面的例子用了两种方法来显示国际化字符串,其输出是相同的。其实,这就是Struts 2.0的一个优势,因为它默认支持EL,所示我们可以用getText方法来简洁地取得国际化字符串。另外更普遍的情况――在使用UI表单标志时,getText可以用来设置label属性,例如:



    <
    s:textfield
    name
    ="name"
      label
    ="% { getText("UserName")}"

    />
    资源文件查找顺序 之所以说Struts 2.0的国际化更灵活是因为它可以能根据不同需要配置和获取资源(properties)文件。在Struts 2.0中有下面几种方法:

    使用全局的资源文件,方法如上例所示。这适用于遍布于整个应用程序的国际化字符串,它们在不同的包(package)中被引用,如一些比较共用的出错提示;
    使用包范围内的资源文件。做法是在包的根目录下新建名的package.properties和package_xx_XX.properties文件。这就适用于在包中不同类访问的资源;
    使用Action范围的资源文件。做法为Action的包下新建文件名(除文件扩展名外)与Action类名同样的资源文件。它只能在该Action中访问。如此一来,我们就可以在不同的Action里使用相同的properties名表示不同的值。例如,在ActonOne中title为“动作一”,而同样用title在ActionTwo表示“动作二”,节省一些命名工夫;
    使用<s:i18n>标志访问特定路径的properties文件。使用方法请参考我早前的文章《常用的Struts 2.0的标志(Tag)介绍》。在您使用这一方法时,请注意<s:i18n>标志的范围。在<s:i18n name="xxxxx">到</s:i18n>之间,所有的国际化字符串都会在名为xxxxx资源文件查找,如果找不到,Struts 2.0就会输出默认值(国际化字符串的名字)。
    上面我列举了四种配置和访问资源的方法,它们的范围分别是从大到小,而Struts 2.0在查找国际化字符串所遵循的是特定的顺序,如图3所示:
    图3 资源文件查找顺序图 假设我们在某个ChildAction中调用了getText("user.title"),Struts 2.0的将会执行以下的操作:  

    查找ChildAction_xx_XX.properties文件或ChildAction.properties;
    查找ChildAction实现的接口,查找与接口同名的资源文件MyInterface.properties;
    查找ChildAction的父类ParentAction的properties文件,文件名为ParentAction.properties;
    判断当前ChildAction是否实现接口ModelDriven。如果是,调用getModel()获得对象,查找与其同名的资源文件;
    查找当前包下的package.properties文件;
    查找当前包的父包,直到最顶层包;
    在值栈(Value Stack)中,查找名为user的属性,转到user类型同名的资源文件,查找键为title的资源;
    查找在struts.properties配置的默认的资源文件,参考例1;
    输出user.title。
    参数化国际化字符串 许多情况下,我们都需要在动行时(runtime)为国际化字符插入一些参数,例如在输入验证提示信息的时候。在Struts 2.0中,我们通过以下两种方法做到这点:

    在资源文件的国际化字符串中使用OGNL,格式为,例如:

      
       validation.require
       =
       $ {getText(fileName)} is required
       
    使用java.text.MessageFormat中的字符串格式,格式为{ 参数序号(从0开始), 格式类形(number | date | time | choice), 格式样式},例如:

      
       validation.between
       =
       Date must between {
       0
       ,
        date, short} and {
       1
       ,
        date, short}
       
    在显示这些国际化字符时,同样有两种方法设置参数的值:


    使用标志的value0、value1...valueN的属性,如:

      
       <
       s:text
       name
       ="validation.required"
        value0
       ="User Name"
       
       />
       
    使用param子元素,这些param将按先后顺序,代入到国际化字符串的参数中,例如:

      
       <
       s:text
       name
       ="validation.required"
       >
       
       
       <
       s:param
       value
       ="User Name"
       
       />
       

       </
       s:text
       >
       
    让用户方便地选择语言 开发国际化的应用程序时,有一个功能是必不可少的――让用户快捷地选择或切换语言。在Struts 2.0中,通过ActionContext.getContext().setLocale(Locale arg)可以设置用户的默认语言。不过,由于这是一个比较普遍的应用场景(Scenario),所以Struts 2.0为您提供了一个名i18n的拦截器(Interceptor),并在默认情况下将其注册到拦截器链(Interceptor chain)中。它的原理为在执行Action方法前,i18n拦截器查找请求中的一个名为"request_locale"的参数。如果其存在,拦截器就将其作为参数实例化Locale对象,并将其设为用户默认的区域(Locale),最后,将此Locale对象保存在session的名为“WW_TRANS_I18N_LOCALE”的属性中。 下面,我将提供一完整示例演示它的使用方法。


    package
      tutorial;


    import
      java.util.Hashtable;

    import
      java.util.Locale;

    import
      java.util.Map;


    public

    class
      Locales

    {
        public Map<String, Locale> getLocales() {
            Map<String, Locale> locales =new Hashtable<String, Locale>(2);
            locales.put("American English", Locale.US);
            locales.put("Simplified Chinese", Locale.CHINA);
            return locales;
        }
    }
    tutorial/Locales.java



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

    %>


    <
    script
    type
    ="text/javascript"
    >


    <!--

         
    function
      langSelecter_onChanged() {
             document.langForm.submit();
         }

    //
    -->


    </
    script
    >


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

    />


    <
    s:bean
    id
    ="locales"
      name
    ="tutorial.Locales"

    />


    <
    form
    action
    ="<s:url includeParams="
    get" encode
    ="true"

    />
    " name="langForm"
         style="background-color: powderblue; padding-top: 4px; padding-bottom: 4px;">
         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
    >
    LangSelector.jsp 上述代码的原理为,LangSelector.jsp先实例化一个Locales对象,并把对象的Map类型的属性locales赋予下拉列表(select) 。如此一来,下拉列表就获得可用语言的列表。大家看到LangSelector有<s:form>标志和一段Javascript脚本,它们的作用就是在用户在下拉列表中选择了后,提交包含“reqeust_locale”变量的表单到Action。在打开页面时,为了下拉列表的选中的当前区域,我们需要到session取得当前区域(键为“WW_TRANS_I18N_LOCALE”的属性),而该属性在没有设置语言前是为空的,所以通过值栈中locale属性来取得当前区域(用户浏览器所设置的语言)。 你可以把LangSelector.jsp作为一个控件使用,方法是在JSP页面中把它包含进来,代码如下所示:

    <
    s:include
    value
    ="/LangSelector.jsp"

    />

    在例1中的HellloWorld.jsp中<body>后加入上述代码,并在struts.xml中新建Action,代码如下:


    <
    action
    name
    ="HelloWorld"
    >

         
    <
    result
    >
    /HelloWorld.jsp
    </
    result
    >


    </
    action
    >

    或者,如果你多个JSP需要实现上述功能,你可以使用下面的通用配置,而不是为每一个JSP页面都新建一个Action。



    <
    action
    name
    ="*"
    >

         
    <
    result
    >
    /{1}.jsp
    </
    result
    >


    </
    action
    >

    分布运行程序,在浏览器的地址栏中输入http://localhost:8080/Struts2_i18n/HelloWorld.action,出现图4所示页面:


    图3 HelloWorld.action

    在下拉列表中,选择“American English”,出现图5所示页面:



    图4 HelloWorld.action


      
       
       
       可能大家会问为什么一定要通过Action来访问页面呢?
    你可以试一下不用Action而直接用JSP的地址来访问页面,结果会是无论你在下拉列表中选择什么,语言都不会改变。这表示不能正常运行的。其原因为如果直接使用JSP访问页面,Struts 2.0在web.xml的配置的过滤器(Filter)就不会工作,所以拦截器链也不会工作。
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-26 13:37 , Processed in 0.366595 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表