struts2国际化

来源:互联网 发布:js权威指南第六版 pdf 编辑:程序博客网 时间:2024/06/06 13:00

原文地址:http://blog.csdn.net/u022812849/article/details/40710957#comments

1.  国际化与本地化

程序国际化已成为Web应用的基本要求。随着网络的发展,大部分的Web站点面对的已经不再是本地或者本国的浏览者,而是来自全世界各国各地区的浏览者,因此国际化成为了Web应用不可或缺的一部分。

国际化Internationalization是使程序在不做任何修改的情况下,就可以在不同的国家或地区和不同的语言环境下,按照当地的语言和格式习惯显示字符。例如,一个数字123456.78,在法国它的书写格式是123  456,78,在德国是123.456,78,而在美国则是123,456.78。

国际化又被称为I18N,因为国际化的英文是Internationalization,它以I开头,以N结尾,中间有18个字母。

一个国际化的程序,当它运行在本地机器时,需要根据本地机器的语言和地区设置显示相应的字符,这个过程就叫做本地化(Localization),通常简称为:L10N。

2.  java国际化

在JAVA中编写国际化程序主要通过两个类来完成:java.util.Locale类和java.util.ResourceBundle抽象类。

1)        Locale类用于提供本地信息,通常称它为语言环境。不同的语言,不同的国家和地区采用不同的Locale对象来表示。

2)        ResourceBundle类称为资源包,包含了特定于语言环境的资源对象。当程序需要一个特定于语言环境的资源时(如字符串资源),程序可以从适合当前用户语言环境的资源包中加载它。采用这种方式,可以编写独立于用户语言环境的程序代码,而与特定语言环境相关的信息则通过资源包来提供。

Java.util.Locale类的常用构造方法如下:

1)        public Locale(String language)

2)        public Locale(Stringlanguage,String country)

其中language表示语言,它的取值是由ISO-639定义的小写的、两个字母组成的语言代码。

其中country表示国家或地区,它的取值由ISO-639定义的大写的、两个字母组成的代码

左表列出了常用的ISO-639语言代码。右表列出了常用的ISO-3166国家和地区

最理想的实现国际化的方法是将要显示的字符内容从程序中分离,然后统一存储到一个资源包中,当显示时,从资源包中取出和Locale对象相一致的字符内容。在Java中,这种资源包是由类来实现的,这个类必须要扩展java.util.ResourceBundle.

在编写国际化程序时,要为不同的国家地区和语言编写不同的资源类,这些资源类同属一个资源系列,共享同一个基名(base name).不同语言所对应的资源类的名称为基名加上ISO-639标准的语言代码,而应用于某个特定国家或地区的资源类的名称,则是在基名和语言代码后加上ISO-3166标准的同家或地区代码。

资源文件的命名规则是非常重要的,其分为如下三种形式:

•       baseName.properties

•       baseName_language.properties

•       baseName_language_country.properties

baseName是资源文件的基本名称,由用户自由定义。但是language和country就必须为Java所支持的语言和国家/地区代码。

例如:中国大陆: baseName_zh_CN.properties

  美国:baseName_en_US.properties

Java中的资源文件只支持ISO-8859-1编码格式字符,直接编写中文会出现乱码。

方法:

•      使用native2ascii.exe命令;

•      安装专门的属性编辑插件:

•      PropertiesEditor插件

•      JInto插件

•      jp.gr.java_conf.ussiy.app.propedit插件

在资源文件中的消息文本可以带有参数,例如:

greeting={0},欢迎学习struts2.

花括号中的数字是一个占位符,可以被动态的数据替换。在消息文本中的占位符可以使用0到9的数字,也就是说,消息文本的参数最多可以有10个。例如:

greeting={0},欢迎学习struts2,今天是星期{1}.

要替换消息文本中的占位符,可以使用java.text.MessageFormat类,该类提供了一个静态方法format(),用来格式化带参数的文本,format()方法定义如下:

public staticString format(String pattern,Object …arguments)

示例

    greeting={0},欢迎学习struts2,今天是星期{1}.

我们编写代码:

Locale loc = Locale.getDefault();

ResourceBundle bundle = ResourceBundle.getBundle(“MyResource”,loc);

String greeting = bundle.getString(“greeting”);

Object[] obj = {"张三",new java.util.Date()};

String msg = MessageFormat.format(greeting,obj);

消息文本中的数字占位符将按照MessageFormat.format()方法参数的顺序(从第二个参数开始)而被替换,在上例中,占位符{0}被“张三”替换,{1}被newjava.util.Date()所替换。此外format()方法参数的顺序是与占位符的数字顺序对应的,而不是与占位符出现在消息文本中的顺序对应。

3.  Struts2对国际化的支持

Struts2的国际化是建立在Java国际化的基础之上的,是使用资源包的方式,通过getBundle()方法来寻找指定Locale相关联的资源包,再从资源包文件中查找指定Key所对应的国际化资源信息。

Struts2框架的底层国际化与Java国际化是一致的,作为一个良好的MVC框架,Struts2将Java的国际化功能进行了封装和简化,开发者使用起来会更加简单快捷。

3.1. 资源文件

资源文件分为以下几种:

1)        Action范围资源文件:在Action类文件所在的路径建立名为ActionName_language_country.properties的文件

2)        包范围资源文件:在包的根路径下建立文件名为package_language_country.properties的属性文件,一旦建立,处于该包下的所有Action都可以访问该资源文件。注意:包范围资源文件的 baseName就是package,不是Action所在的包名。

3)        全局资源文件

          i.             命名方式如下:basename_语言_国家.properties,保存目录为src目录下。

        ii.             当准备好资源文件之后,我们可以在struts.xml中通过struts.custom.i18n.resources常量把资源文件定义为全局资源文件,如下:

<constantname=“struts.custom.i18n.resources” value=“app” />,其中app为资源文件的基本名

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

3.2. Action中访问国际化资源文件

Struts2中的Action可以通过三种方式来加载资源文件,包括指指定全局资源文件、包范围资源文件、Action范围资源文件。并且对于不同范围的资源文件有不同的加载顺序。


3.3. 国际化信息的输出

1)        在JSP页面中:

使用<s:text name=“”/>标签输出国际化信息:

<s:text name=“user”/>,name为资源文件中的key

2)        在Action类中:

可以继承ActionSupport,使用getText()方法,该方法的第一个参数用于指定资源文件中的key。

3)        在表单标签中:
通过key属性指定资源文件中的key,如:<s:textfield name="realname" key="user"/>

或者<s:textfieldname=“realname”label=“%{getText(‘user’)}” />

3.4. 实例 使用超链接实现语言切换

1)        用eclipse新建一个dynamic web project,命名为i18nDemo

2)        引入struts2的基本jar包

3)        编辑资源描述符文件web.xml文件,添加如下代码:

    <filter>

        <filter-name>struts2</filter-name>  <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>

    </filter>

    <filter-mapping>

        <filter-name>struts2</filter-name>

        <url-pattern>/*</url-pattern>

    </filter-mapping>

4)        在src目录下创建struts.xml文件,具体代码如下:

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts PUBLIC

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

         "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>

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

         <package name="default" namespace="/" extends="struts-default">

                   <action name="i18n" class="com.morris.action.LoginAction"

                            method="change">

                            <result name="login">/login.jsp</result>

                   </action>

         </package>

</struts>

5)        在src目录下创建i18n_zh_CN.properties文件,具体代码如下:

loginTitle=\u767B\u5F55 \u9875\u9762

userId=\u8D26\u53F7

userPassword=\u5BC6\u7801

submit=\u63D0\u4EA4

6)        在src目录下创建i18n_en_US.properties文件,具体代码如下:

loginTitle=Login Page

userId=UserName

userPassword=Password

submit=Submit

7)        编写login.jsp页面

<%@ page language="java" contentType="text/html; charset=utf-8"

         pageEncoding="UTF-8"%>

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

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">

<title>Insert title here</title>

</head>

<body>

         <h4>

                   <s:text name="loginTitle"></s:text>

         </h4>

         <a href="i18n.action?language=zh">中文</a>

         <a href="i18n.action?language=en">English</a>

         <s:form action="*">

                   <s:textfield name="userId" key="userId" />

                   <s:textfield name="userPassword" key="userPassword" />

                   <s:submit key="submit"></s:submit>

         </s:form>

</body>

</html>

8)        编写LoginAction.java文件

package com.morris.action;

import java.util.Locale;

import com.opensymphony.xwork2.ActionContext;

import com.opensymphony.xwork2.ActionSupport;

public class LoginAction extends ActionSupport {

         private static final long serialVersionUID = 1L;

         public String getLanguage() {

                   return language;

         }

         public void setLanguage(String language) {

                   this.language = language;

         }

         private String language;

 

         public String change() {

 

                   Locale locale = Locale.getDefault();

                   if ("zh".equalsIgnoreCase(language)) {

                            locale = new Locale("zh", "CN");

                            ActionContext.getContext().setLocale(locale);

                   } else {

                            locale = new Locale("en", "US");

                            ActionContext.getContext().setLocale(locale);

                   }

 

                   return LOGIN;

         }

 

}

工程目录如下:


运行结果如下:

0 0