struts2-国际化资源

来源:互联网 发布:常用生物数据分析软件 编辑:程序博客网 时间:2024/06/04 20:11
今天学习的主要内容:国际化资源
一.首先回顾一下struts2 的搭建有三个步骤:
1.导入包;
2.配置web-inf下的xml文件;
3.把struts.xml放在src的目录下。

二.分析action和Action类
1.action:代表一个struts2 的请求。
2.Action类:能处理struts2请求的类(java文件,实质是:.class文件)
Action的特点:
》属性的名字必须遵JavaBeans属性名相同的命名规则。属性的类型可以是任意的,从字符串到非字符串(基本数据类型)之间数据转换可以自动发生。
》必带一个无参数的构造器,因为要通过反射构建需要类的实例。
》至少有一个struts在执行action时候调用的方法。
》同一个Action类可以包含多个action的方法。
》struts2会给每一个请求创建一个Action的实例,即Action不是单例的。

三.这里顺便插入一个小注意事项:
在<form action="" >中,若不写method,默认值为:method="get",所以几次出错的原因,没有改写默认的method的值。所以只要把method="post",就不会乱码。

四.Struts2国际化资源
》国际化资源的概念:为不同的国家语言提供对应的消息资源文件。
》Struts2框架会根据请求包中包含的locale加载对应的资源文件。
》通过程序代码取得资源文件指定的key对应的消息。
重点:
1.如何配置消息资源的文件?
2.页面和Action类中如何取得资源配置中的value的值?
3.如何通过超链接实现国际化资源的替换?

首先看第一点:如何配置资源文件
(1)Action范围资源文件的配置:直接可以写XXXXAction_zn_CN.properties,这里一定要注意是:Action_zn_CN.properties这样的格式必须写Action,规定的。
(2)包范围的资源文件:在包的根目录下创建。文件名也要强制:package_language_country.properties属性文件,
一旦建立,处于该包下的所有Action都可以访问该文件,注意:包范围资源文件的baseName就是package(小写的p),不是Action所在的包名。
(3)全局资源文件:命名方式:baseName_language_country.properties,这个全局的要通过常量方式配置。
在struts.xml中我们要:
<constant name="struts-custom.i18n.resources" value="baseName"/>
了解下国际化资源的加载顺序:距离当前的Action较近的将被优先加载。(只要明白这一点就可以了)

再来看下第二点:页面和Action类中如何取得资源配置中的value的值
(1)在Action类中,若Action实现了TextProvder接口,则可以调用其getText方法获取value值(通过继承ActionSupport的方式)
下面看一个例子:
在全局中写3个,一个是i18nAction.properties,一个是中文i18n_zh_CN.properties,一个是美国英文i18n_en_US.properties
Testi18nAction.properties资源文件内容如下:
username=UserName
password=PassWord
submit=Submit
time=Time:{0}
time2=Time:${date}

i18n_zh_CN.properties资源文件如下:
username=\u7528\u6237\u540D
password=\u5BC6\u7801
submit=\u63D0\u4EA4
time=\u65F6\u95F4\:{0}
time2=\u65F6\u95F4\:${date}

i18n_en_US.properties资源文件如下:
username=UserName
password=PassWord
submit=Submit
time=Time:{0}
time2=Time:${date}

然后在struts.xml中配置全局的,constant的详细配置过程:(<!---->是xml中的注释)
<!-- 配置国际化资源文件,找到i18n:路径项目中的web App Libraies>>strust2-core-2.3.28.jar>>org.apache.struts2>>
    下面注意观察找到default.properties>>然后ctrl+F查找i18n找到:
    “# struts.custom.i18n.resources=testmessages,testmessages2” 
    然后constant中:
    (i18n名字随意的可以是其他的,但是要跟写的.properties文件名对应)
    的name复制等号前面的:struts.custom.i18n.resources
    value的值:i18n
    -->
    <constant name="struts.custom.i18n.resources" value="i18n"></constant>
    <package name="default"  extends="struts-default">
        <action name="testi18n" class="com.atguigu.struts2.i18n.app.Testi18nAction">
            <result>/i18n.jsp</result>
        </action>
    </package>
这个例子的2个页面都在webroot下
一个是:
             index.jsp
内容:
<a href="testi18n">Test i18n</a>
二个是:il8n.jsp(在下面有讲解这个jsp页面的详细内容提示在这个地方:”再看页面中获取资源文件信息:il8n.jsp“)
然后在配置好的struts2的一个web项目中的src下创建如下图的包名和名字为testi18nAction.java文件
仔细看下面的代码注释和内容:
mport java.util.Arrays;
import java.util.Date;
import com.opensymphony.xwork2.ActionSupport;
public class Testi18nAction extends ActionSupport {
    /**
     * 这里要注意2个地方
     * 
     * 这是第一点:在建立这个类的时候 Testi18nAction可以直接去继承找到ActionSupport。
     * 
     * 第二点:静态的常量有2个,可以写第一个,并且写execute的时候可以直接写ex之后ctrl+/提示这个execute() 
     * 方法的重写。
     */
    private static final long serialVersionUID = 1L;
    //为了是页面访问time所以定义一个字段如下:
    //然后在execute方法中去实例化对象:
    //date = new Date()写出这个的get与set方法;
    private Date date = null;//定义一个全局变量Date类的date
    public Date getDate() 
    {
        return date;
    }
    public void setDate(Date date) 
    {
        this.date = date;
    }
    //
    @Override
    public String execute() throws Exception
    {
        /**
         * 在action中访问国际化资源文件的value值;
         * 为什么能访问这个值?
         * 因为这个类Testi18nAction继承ActionSupport,这个ActionSupport中有个getText(String key)方法实现国际化;
         * getText方法好像实现了一个接口?
         * 所以这个方法的返回值就是国际化资源的value的值;
         * 占位符的time:
         * String time = getText("time", Arrays.asList(new Date()));
         */
        String username = getText("username");//这一行代码就是获取资源配置中的value的值
        System.out.println(username);
        date = new Date();
        String time = getText("time", Arrays.asList(date));//这一行代码也是获取资源配置中的key,并赋值
        System.out.println(time);
        return SUCCESS;
    }
}
再看页面中获取资源文件信息:il8n.jsp
首先在设置UTF-8下面一行写:
<%@taglib prefix="s" uri="/struts-tags" %>
整体页面和注释如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!-- 导入Struts2标签 -->
<%@taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'il8n.jsp' starting page</title>
  </head>
  <body>
          <!-- 打开debug的方法在jsp页面中要加上<%@taglib prefix="s" uri="/struts-tags" %>
          之后才可以
          打开网页之后我们点击打开debug可以知道栈顶部有一个:DefaultTextProvider,在他里面有许多的get方法。
          所以在下面的form表单下的第一个label="UserName" 可以改写成label="getText('username')"

          getText('username')这个是ognl表达式
          而label=“字符串值”,所以强制ognl包装解析:


          小结:一·所以有2种情况(默认的theme为xml情况):
          label="%{getText('username')}"(页面获取的第一种方式)
          1)用key属性 例如:<s:textfield name="username" key="username"></s:textfield>(页面获取第二种方式)
          2)用label属性<s:textfield name="username" label="%{getText('username')}"></s:textfield>

          下面的二·是theme是simple的情况(<s:text name="username"/>加在前面)
            <s:text name="username"/>:<s:textfield name="username" label="%{getText('username')}"></s:textfield>
             <s:submit key="submit" value="%{getText('submit')}"></s:submit>
          -->
          <s:debug></s:debug>
          <!-- label方式把label写死在标签里 ,但是可以访问资源文件-->
           <s:form action="" theme="simple">
           <!--
           二· 
           这里的表单主体默认是xml,若将主题换成theme="simple"
           则不会出现账号,密码的文字信息提示用户输入了,所以
           要加上<s:text name="username"/>,这个标签的作用也可访问国际化资源的value值
           所以在<s:textfield name="username" key="username"></s:textfield>
           前面,而submit也在simple的情况下也要ognl解析:
           <s:submit key="submit" value="%{getText('submit')}"></s:submit>
            -->
               <s:text name="username"/>:<s:textfield name="username" label="%{getText('username')}"></s:textfield>

           <!-- key直接上资源文件中的value的值 -->
               <s:text name="username"/>:<s:textfield name="username" key="username"></s:textfield>
               <s:text name="password"/>:<s:textfield name="password" key="password"></s:textfield>

               <s:submit key="submit" value="%{getText('submit')}"></s:submit><!-- 因为这里是struts2标签,所以要用ognl解析才可以 -->
           </s:form>

           <!-- 访问值栈里面的属性值:time=Time:{0}这样的形式,要param填充占位符-->
          
           <!-- date是值栈栈顶中的属性值,在servlet中已经获取了国际化资源Testi18nAction.java中;
           在 i18n_zn_CN.properties中或者在i18n_en_US.properties中可以直接获取值栈中的date
           time:${date}
           -->
            //这样的写发在资源文件中的样子是:time=Time{0}
          <s:text name="time">
                      <s:param value="date"></s:param>
           </s:text>
           <br>
            //这样写法在资源文件中time2=${date},这个date的来历是在testi18nAction.java中定义了这个date值
           <s:text name="time2"></s:text>
  </body>
</html>
如此,在Action范围的情况下如下图所示在Testi18nAction.java同级别目录下写3个test开头的文件,里面内容与上面的全局资源里一样,可以测试出加载资源文件的优先级(可以在这个三个值前面加一个"^0^"的符号测试):

0 0