j2ee国际化的研究,基于SSH

因为遇到了国际化的需求,研究了一下特此记录!java

静态国际化(页面中比较固定元素如,导航,按钮,label等)
web

基于Struts2能够实现国际化数据库

  • 将须要国际化的元素保存成applicationResource_en_US.properties和applicationResource_zh_CN.properties,有几国语言就保持几份。app

  • 在Struts.xml中添加 webapp

<constant name="struts.custom.i18n.resources" value="applicationResource">
</constant><constant name="struts.i18n.encoding" value="UTF-8" />

  • 在jsp页面中获取国际化字符串的方法:<s:text name="webapp.footer" />jsp

  • 在action中获取国际化字符串的方法:getText函数数据库设计

  • 在普通java文件中获取国际化字符串方法:因为普通java文件没有getText函数,只能写个工具类根据当前语言环境获取不一样资源文件中的值
    函数

public class ApplicationResourceProperties {

	private ApplicationResourceProperties() {

	}
	
	private static ResourceBundle rb;
	
	public static synchronized void reload(){
		//rb = ResourceBundle.getBundle("applicationResource");// 这句话就是绑定了名为application的资源文件,后缀都不用写的
	}

	public static String getValue(String key) {
		
		
		Locale l=(Locale) ServletActionContext.getRequest().getSession().getAttribute("WW_TRANS_I18N_LOCALE");
		if(l==null)
		{
			l=ServletActionContext.getRequest().getLocale();
		}
		ResourceBundle rb=ResourceBundle.getBundle("applicationResource", l);
		String temp = rb.getString(key);
		return temp;
	}
	
	static{
		reload();
	}

}

  • 若是须要国际化的资源保持在数据中,可采用以下方式实现国际化(适合元素相对固定,不会常常改变)工具

<s:property value="%{getText(us_classname)}"/>  <!-- 先获取数据库中us_classname对应的值,好比:InstructionForProduct,再去资源文件中找"InstructionForProduct"对应的值 -->

动态国际化(元素保持在数据库中,且会常常变化)spa

    (1)采用冗余数据的方式存储国际化数据。在数据库表中引入 标识语种的 LocaI 字段,每一条原始数据记录在国际化的数据表中 都对应有多条各类语言的记录。这种方案能够解决国际化数据的存 储和访问的问题,可是,数据表中和国际化无关的字段会有冗余数 据,数据更新也须要涉及全部语种的记录以维护数据的一致性,从 而增长了系统运行时的开销。

     (2) 采用单表存储国际化数据。在数据库中用专门的数据表维 护国际化数据,记为 LocaITabIe ,其余数据表的国际化字段存储 LocaITable 表中记录的主键值,经过主键值与 LocaITable 表关联。 这种方案将国际化数据和非国际化数据分离开来,减小了冗余数据, 提升了数据一致性,不过,用单表存储会形成单表数据过多,从而 增长对该表的访问时间。因为国际化的J2EE 系统对国际化数据的插 入、修改、删除等访问操做会比较频繁,在系统数据量超过→定规 模的状况下,这种方案将大为下降系统的执行效率。

     针对以上两种设计方案各自的优点和缺点,将这两种方 案结合,并在此基础上引入分表的概念,提出了一种混合的 数据库设计方案。这种方案既能够减小冗余数据,维护数据 的一致性,又能够保证系统的访问效率。 

    经过分析数据能够发现,系统存储在数据库中的数据可 以分为两种类型。第 种类型的数据通常在系统启动的时候 加载,在系统运行时被访问,但基本不进行修改和删除操做。 这种数据通常是系统的固有信息的描述,好比国家列表、省 市列表等。第 种类型的数据在系统运行时产生,并且在运 行时会有比较多的添加、修改和删除操做。这种类型的数据 在国际化数据中占大多数。针对这两种不一样类型的数据,采 用了不一样的国际化方法。

     对于第1 种类型的数据,因为访问操做比较少,并且一 般能够在系统运行时能够直接载入内存,所以采用单表存储 的方式,能够在不影响系统执行效率的前提下,避免相关冗 余数据的出现。对于第 2种类型的数据,因为访问操做会比 较频繁,在系统运行时的数据积累常常会超过必定规模,不 适宜用单表操做,所以采用在数据表中添加标识语种的 Local 字段的方式来存储。为了解决上文提到的这种方式所存在的 数据冗余和一致性的问题,提出了分表的方法。

    冗余数据是因为非国际化字段的存在而产生的,也正是 因为冗余数据的存在,才引起了数据一致性的问题。若是将 国际化和非国际化字段分开,将原始表拆分红两个表,就可 以免冗余数据的产生。咱们提出的分表的方法正是基于这 一思想。分表的具体方法以下: 对于原始表 A(问叶 川儿 ,其中 key 是表 的主键字段, (i=1 ,… n) 是表 的非主键字段,将 拆分红两个表 A' (key ,fml ,fm2 ,...,f Aúx:al(时剧,flq ,fk2 门儿) ,其中 1m; (i =1 ,..., p) 是表 的非国际化字段, hj (j=I ,2 ,... q) 的国际化字段,表 的主键字段是 key ALocal key local 为复合主键。 这种分表的方式既避免了冗余数据的出现,也保证了数 据的一致性。《 不过,这种方法也有不利之处。原始表的拆分使得对原 始数据表的访问一般须要转变成对两个拆分后的表的同时访问

 (3).在数据库中,对于须要国际化的元素,数据库中对应多列,列名包含语言信息。例如航空公司默认名称对应列AirelineName,英文名称对应AirelineName_en,简体中文名称对应AirelineName_zh.对应的java对象属性名称保持这种命名风格。利用java反射机制,经过统一的接口获取语言相关的航空公司名称,代码以下:

public static String localize(String localeString,Object obj,String method){
    Class cla = obj.getClass();//取得Class对象
    Method m = cla.getMethod(method+localeString,null);//取得语言信息相关的方法
    String str = String.valueOf(m.invoke(obj,null)); //执行方法,结果为String
    if(str == null) str= "";
    return str;    
}

    接口中,localeString为标识语言信息的字符串,如“_en”。obj为JAVA对象,method为获取默认属性的方法名。

相关文章
相关标签/搜索