[学习笔记]Struts国际化 - 消息资源

第一步 资源包内容(国际化)

默认情况下,Struts默认的资源文件为ApplicationResources.properties文件。

 

资源文件可为一个束,可针对不同的语言,写不同的资源文件,开发人员可以定义英文、简体中文、繁体中文、日文等资源文件,资源文件的命名格式为:资源文件名_国别_语言.properties,常见的资源文件名称为:

 

       ApplicationResources.properties:默认资源文件

       ApplicationResources_en.properties:英文资源文件

       ApplicationResources_zh_CN.properties:简体中文

       ApplicationResources_zh_TW.properties:繁体中文

 

每一个资源文件都是-对的集合,例如可在src目录下的资源文件ApplicationResources.properties中,编写如下内容:

UserForm.userName = USERNAME

UserForm.password = PASSWORD

 

同时在src目录下建立ApplicationResources_zh_CN.properties.bak文件来编写简体中文的原始资源文件内容如下

UserForm.userName = 用户名

UserForm.password = 密码

 

开发人员还可以建立ApplicationResources_zh_TW.properties.bak文件编写繁体中文的原始资源文件。其内容如下:

UserForm.userName = ノめ?W

UserForm.password = ノめ?W

 

 

 

对于简体中文和繁体中文文件,开发人员还需要对其使用native2ascii工具对其进行转换,将非ASCII码转换为Unicode编码,native2ascii工具在%JAVA_HOME%/bin目录下的native2ascii.exe,因此若要进行这种转换,读者首先需要安装了该工具。安装了该工具之后,进入其所在目录,运行native2ascii…命令可进行编码转换,为了能在命令行直接使用该命令,读者还需要在系统变量PATH中添加路径:%JAVA_HOME%"bin

 

在实际项目中,一般编写一个批处理文件(eg. code.bat)来处理资源文件的编码,例如code.bat为如下内容时,可满足要求将如上的ApplicationResources_zh_CN.properties.bak文件进行编码,并将编码后的信息放入ApplicationResources_zh_CN.properties文件中。该批处理文件的内容如下所示:

 

del ApplicationResources_zh_CN.properties

 

copy ApplicationResources_zh_CN.properties.bak ApplicationResources_zh_CN.properties.gbk

 

native2ascii -encoding GBK ApplicationResources_zh_CN.properties.gbk ApplicationResources_zh_CN.properties

 

del ApplicationResources_zh_CN.properties.gbk

 

del ApplicationResources_zh_TW.properties

 

copy ApplicationResources_zh_TW.properties.bak ApplicationResources_zh_TW.properties.big5

 

native2ascii -encoding Big5 ApplicationResources_zh_TW.properties.big5 ApplicationResources_zh_TW.properties

 

del ApplicationResources_zh_TW.properties.big5

 

del *.bak.bak

 

 

运行code.bat之后,可看到目录下多出了两个资源文件,即:ApplicationResources_zh_CN.propertiesApplicationResources_zh_TW.properties。其中ApplicationResources_zh_CN.properties的内容是经过编码的,内容如下:

UserForm.userName = "u7528"u6237"u540d

UserForm.password = "u5bc6"u7801

 

 

jsp页面中,可以通过Struts的自定义标签来获取默认资源文件(<message-resources>标记中未设置key的资源配置)的某个键(例如:UserForm.userName)的信息。示例如下

<bean:message key="UserForm.userName"/>

 

http://www.blogjava.net/amigoxie/archive/2008/01/05/172927.html

 

 

 

 

第二步 配置消息资源包

struts-config.xml配置文件中增加结点<message-resources />

<!-- The "message-resources" element describes a MessageResources object with

     message templates for this module. The following attributes are defined:

 

     className       The configuration bean for this message resources object.

                     If specified, the object must be a subclass of the default

                     configuration bean.

                     ["org.apache.struts.config.MessageResourcesConfig"]

                     此资源束的配置bean

 

     factory         Fully qualified Java class name of the

                     MessageResourcesFactory subclass to use for this message

                     resources object.

                     ["org.apache.struts.util.PropertyMessageResourcesFactory"]

                     自定义MessageResourcesFactory的一个子类

 

     key             Servlet context attribute under which this message

                     resources bundle will be stored. The default attribute is

                     the value specified by the string constant at

                     [Globals.MESSAGES_KEY]. The module prefix (if

                     any) is appended to the key (${key}${prefix}).

                     [org.apache.struts.Globals.MESSAGES_KEY]

                    

                     NOTE: The module  prefix includes the leading

                     slash, so the default message resource bundle for a module

                     named "foo" is stored under

                     "org.apache.struts.action.MESSAGE/foo".

                     指定存储此资源束的上下文属性关键字。

                     默认值由org.apache.struts.Globals.MESSAGES_KEY指定。

                     一个应用程序只允许一个资源束设定为默认值。

 

     null            Set to "true" if you want our message resources to return a

                     null string for unknown message keys, or "false" to return a

                     message with the bad key value.

                     表示缺少信息时是否返回空值

 

     parameter       Configuration parameter to be passed to the createResources

                     method of our factory object.

                     资源束的名称。如果资源束名称为cn.rolia.ApplicationResources.properties

                     则此处的值设为:con.rolia.ApplicationResources

-->

<!ELEMENT message-resources (set-property*)>

<!ATTLIST message-resources id          ID              #IMPLIED>

<!ATTLIST message-resources className   %ClassName;     #IMPLIED>

<!ATTLIST message-resources factory     %ClassName;     #IMPLIED>

<!ATTLIST message-resources key         %AttributeName; #IMPLIED>

<!ATTLIST message-resources null        %Boolean;       #IMPLIED>

<!ATTLIST message-resources parameter   CDATA           #REQUIRED>

http://blog.csdn.net/yiyi735/article/details/2498745

 

常用的三条属性:

1. key: 资源包的名称,不写则作为默认资源包存在

在页面通过<bean:message>标签显示资源包内消息,不使用bundle来指明要使用那个资源包时,调用未设置key属性的资源包配置.

2. parameter: 指明资源包的位置

e.g. parameter="com.iteye.jarg.resources.ApplicationResources"

表明资源包路径为src/com/iteye/jarg/resources/ApplicationResources.properties

部署后路径为WebRoot/WEB-INF/classes/com/iteye/jarg/resources/ApplicationResources.properties

3. null: 设置true,当要调用未在资源包中配置的消息时,返回一个空值(null),产生异常javax.servlet.ServletException;若设置为false,则返回一个错误的消息,形如:???zh_CN.login.legend2???.默认为true.

 

需要注意的是,经常会遇到如下异常:

exception

org.apache.jasper.JasperException: java.lang.NullPointerException

        org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:500)

        org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:428)

        org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)

        org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)

        javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

root cause

java.lang.NullPointerException

        org.apache.struts.taglib.TagUtils.retrieveMessageResources(TagUtils.java:1161)

        org.apache.struts.taglib.TagUtils.message(TagUtils.java:1024)

        org.apache.struts.taglib.bean.MessageTag.doStartTag(MessageTag.java:224)

        org.apache.jsp.index_jsp._jspx_meth_bean_005fmessage_005f0(index_jsp.java:200)

        org.apache.jsp.index_jsp._jspService(index_jsp.java:78)

        org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)

        javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

        org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:386)

        org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)

        org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)

        javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

 

解决办法:

web.xml配置Struts ActionServlet处添加下面红色代码.

当未设置<load-on-startup>或者其值为负数时,servlet只有在被选择时才加载.这里被选择的意思,可以理解为当有*.do的页面请求时,ActionServlet才被加载,然后完成一些Servlet的初使化工作,struts-config.xml被加载,消息资源包被加载.

由于下一步在jsp页面中会使用<bean:message>标记来显示资源消息时,要求消息资源已经加载.

设置<load-on-startup>值为0或者大于0的数,让容器在应用启动时就加载这个servlet,使得消息资源包在容器加载jsp页面前被加载.

 

<servlet>

  <servlet-name>ActionServlet</servlet-name>

  <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>

 

  <load-on-startup>0</load-on-startup>

</servlet>

 

Servlet specification:

The load-on-startup element indicates that this servlet should be loaded (instantiated and have its init() called) on the startup of the web application. The optional contents of these element must be an integer indicating the order in which the servlet should be loaded. If the value is a negative integer, or the element is not present, the container is free to load the servlet whenever it chooses. If the value is a positive integer or 0, the container must load and initialize the servlet as the application is deployed. The container must guarantee that servlets marked with lower integers are loaded before servlets marked with higher integers. The container may choose the order of loading of servlets with the same load-on-start-up value.

 

译文:

servlet的配置当中,<load-on-startup>0</load-on-startup>的含义是:

标记容器是否在启动的时候就加载这个servlet

当值为0或者大于0时,表示容器在应用启动时就加载这个servlet

当是一个负数时或者没有指定时,则指示容器在该servlet被选择时才加载。

正数的值越小,启动该servlet的优先级越高。

 

http://blog.csdn.net/enjoyo/article/details/1761033

 

 

第三步 使用资源消息

一般采用<bean:message>标记来显示资源包中消息

可以根据国际化需要,配置多个语言资源包(.properties文件),将这些语言资源包配置到<message-resources>标签中.然后在前台页面通过更改<bean:message>标签中bundle属性值来实现消息内容更换.

 

例如:目前配置了简体中文语言资源包zh_cn.properties和英文语言资源包en_properties

当要显示简体中文消息时,<bean:message>标签中bundle属性值设置为zh_cn

当要显示英文消息时,<bean:message>标签中bundle属性值设置为en

 

 

提前假设<message-resources key="zh_cn" parameter="zh_cn.properties">

<bean:message>标签使用三种方式:

 

第一种方式是最常用方法

1. <bean:message bundle="zh_cn" key="login.username.label" />

<bean:message bundle="zh_cn" key="login.username.label" />

bundle对应于struts-config.xml<message-resources>标签属性key

key对应于<message-resources>标签属性parameter值指示的资源包中消息内容,不同于<message-resources>标签属性key,特别容易混淆.

注意: 如果<bean:message>中设置了属性bundle,那么<message-resources>中一定要设置属性key,否则运行时会报错.

 

 

对于下面二种方式,都设置有name属性,用来与scope范围(request,session,application,page)中的attribute对应.意思是取出scope范围中的name值的属性值,并把该属性值当作键从资源包中取出消息内容.

另外,第三种方式额外设置有property属性.这种方式是从scope范围取出的是一个JavaBean,property属性指示JavaBean的属性名,把该属性值当作键从资源包中取出消息内容.

2. <bean:message>中标签中的属性name指定一个scope中的key,value为资源配置文件中的key.

例如:

<% request.setAttribute("someBean","login.username.label") %>

<bean:message bundle="zh_cn" name="someBean" />

login.username.label对应于zh_cn.properties中的消息内容

 

3. 同时指定<bean:message>标签的nameproperty属性

name指定一个JavaBean,property指定JavaBean中的一个get方法

get方法的返回值就是资源配置文件中的key.

例如:

<%

SomeBean bean = new SomeBean();

bean.setName("login.username.label");

request.setAttribute("someBean",bean);

%>

<bean:message bundle="zh_cn" name="someBean" property="name" />

bundle对应<message-resources>中的key

name对应request中的属性(someBean)

property对应beangetName()方法

getName()返回对应资源配置文件中键login.username.label的消息内容

 

 

猜你喜欢

转载自jarg.iteye.com/blog/1136599