Struts2国际化

本文深入探讨了Java程序的国际化实现方法,包括利用ResourceBundle、Locale和MessageFormat等类进行资源文件管理,以及如何在Struts2框架中进行国际化配置与动态切换。详细介绍了国际化资源文件的命名规则、加载机制、访问方式和动态切换机制。
摘要由CSDN通过智能技术生成

Java国际化
       Java程序的国际化思路是将程序中的标签、提示信息等放在资源文件中,程序需要支持国家/语言环境,则必须提供对应的资源文件。资源文件是key-value对,每个资源文件中的key不变,但value随不同的国家/语言变化。


Java国际化主要通过如下3个类完成
       Java.util.ResourceBundle:用于加载资源包
       Java.util.Locale:对应一个特定的国家/地区、语言环境
       Java.text.MessageFormat:用于将消息格式化

资源文件的命名可以是如下3种形式:
       baseName_language_country.properties
       baseName_language.properties
       baseName.properties
       其中baseName是资源文件的基本名称,用户可以自由定义,而language和country都不可随意变化,必须是Java所支持的语言和国家。Java支持的国家和语言可以通过Locale.getAvailableLocales();获得。

public static void main(String[] args) {
	Locale [] locales = Locale.getAvailableLocales();
	for(Locale locale:locales){
	//输出所有支持的国家
	System.out.print(locale.getDisplayCountry()+":"+locale.getCountry());
	//输出所有支出的语言
	System.out.println(locale.getDisplayLanguage()+":"+locale.getLanguage());
	}
}

 

Java国际化实例

资源文件及内容:

resource_zh_CN.properties
       title=标题
resource_en_US.properties
       title=title

package com.ascent.i18n.test;
import java.util.*;
public class ResourceBundleTest {
	public static void main(String[] args) {
		//设置本地区语言(默认)
		Locale locale = Locale.getDefault();
		//可以使用Local的常量设置具体的语言环境
		//Locale locale = Locale.US;
		//根据地区不同加载不同的资源文件
		ResourceBundle rb = ResourceBundle.getBundle("resource", locale);
		//根据key获得value值
		String title = rb.getString("title");
		System.out.println(title);
	}
}


Java国际化包含占位符的消息

通过MessageFormat.format(String pattern,Object… values) ;返回。

package com.ascent.i18n.test;
import java.util.Date;
import java.util.Locale;
import java.util.ResourceBundle;
import java.text.*;
public class MessageFormatTest {
	public static void main(String[] args) {
		Locale locale = Locale.getDefault();
		ResourceBundle rb = ResourceBundle.getBundle("resource", locale);
		String hello = rb.getString("hello");
		String result = MessageFormat.format(hello, "焦学理",new Date());
		System.out.println(result);
	}
}


Struts2的国际化
        Struts2国际化是建立在Java国际化的基础之上,一样也是通过提供不同国家/语言环境的消息资源,然后通过ResourceBundle加载指定Locale对应的资源文件,再取得该资源文件中指定key对应的消息---整个过程与Java程序的国际化完全相同,只是Struts2框架对Java程序国际化进行了进一步封装,从而简化了应用程序的国际化。

struts2中需要做国际化的:
    jsp页面的国际化,action错误信息的国际化,转换错误信息的国际化,校验错误信息的国际化。

Struts2中加载全局资源文件,多个文件用逗号隔开

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

struts.properties
struts.custom.i18n.resources=baseName

资源文件内容
a.不带参数:key=value
b.带索引参数:key={0}value{1}
c.带表达式参数:key=${username}value 表示从ValueStack中直接获得username变量值,此种方式不需要像(b)那样手动传递参。


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

(1)JSP页面:<s:text name="key"/>
(2)Action类中:使用ActionSupport类的getText方法。
(3)表单元素的Label中:为表单元素指定一个key属性
(4)验证框架xml配置文件ActionName-validation.xml中:<message key="username.xml.invalid"/>

Struts2填充带占位符的国际化消息
(1)JSP页面,在<s:text.../>标签中使用多个<s:param.../>标签来填充消息中的占位符。
(2)Action中,在调用getText方法时使用getText(String aTextName,List args)或getText(String key, String[] args)方法来填充占位符。

4类资源文件  优先级:全局<包范围<类范围
(1)全局范围,在classes路径下:baseName-language-country.properties。通过 <constant name="struts.custom.i18n.resources" value="baseName"/>加载。
(2)包范围,在包根路径下:package-language-country.properties。处于该包下的所有Action都可以访问该资源文件。注意:包范围资源文件的baseName就是package,不是Action所在的包名。
(3)类范围,在该Action类同一路径下:actionName-language-country.properties。
(4)临时资源文件,在jsp页面使用<s:i18n.../>标签的name属性来指定classes路径下的资源文件。


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。

所以最简单的实现动态切换国际化的方法是,请求一个action时增加参数request_locale,参数值为语言国家名,如:
<a href="m.action?request_locale=en_US">美国</a>
<a href="m.action?request_locale=zh_CN">中国</a>

其它实现方式:

<%@ 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>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值