最近一段时间,一直在研究struts2中的国际化实现方案.
对于struts2中标签的国际化中,key值的搜索顺序如下:
假设我们在某个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的字符串值。
后来我自定义了标签后,也想实现类似的功能.结果找来找去,
- 要么需要在相关方法中指定包名如下面的:public static String getString(String baseName,String key)
- 要么只能在全局资源文件中查找key值,如下面的:public static String getString(String key)
基本上很难实现struts标签中getText("user.title")或<s:text name="ttile"/>的查找方式.
再后来,参考了开源控件extremecomponents项目的代码,再加上ec-ext.jar中的部分代码,才找到解决方案.
废话不说了,先晒代码:
/**
*
* 访问资源文件的方法
* @author zhangpf
*
*/
public class ResourceUtil {
/**
* zhangpf 借用ectable中的国际化机制来实现国际化
*/
protected TextProvider textProvider;
public ResourceUtil(PageContext pageContext)
{
//初使化国际化相关的变量
ValueStack stack = TagUtils.getStack(pageContext);
Iterator iter = stack.getRoot().iterator();
Object o=null;
do
{
if(!iter.hasNext())
break;
o = iter.next();
} while(!(o instanceof TextProvider));
textProvider = (TextProvider)o;
}
/**
* 该方法适合用在jsp的标签实现类中
* 此方法寻找属性文件的顺序和路径与一般的struts2标签中的用法一样.比如<s:text标签
* 国际化相关的方法:传入key值,取出对应的value
* @param code
* @return
*/
protected String getMessage(String code)
{
return getMessage(code, null);
}
protected String getMessage(String code, Object args[])
{
List theArgs = null;
if(args != null)
{
theArgs = new ArrayList();
Object arr[] = args;
int len = arr.length;
for(int i = 0; i < len; i++)
{
Object arg = arr[i];
theArgs.add(arg);
}
}
String message = null;
if(textProvider != null)
message = textProvider.getText(code, null, theArgs);
else
return code;
return message;
}
/**静态方法
* 通过全局资源文件来取值
* @param key
* @return
*/
public static String getString(String key)
{
Locale locale = Locale.getDefault();
String value=LocalizedTextUtil.findDefaultText(key,locale);
return value==null?key:value;
}
/**
* 静态方法
* 指定资源文件取值
* @param baseName
* @param key
* @return
*/
public static String getString(String baseName,String key)
{
try{
Locale locale = Locale.getDefault();
ResourceBundle bundle = ResourceBundle.getBundle(baseName,locale);
String value=bundle.getString(key);
return value==null?key:value;
}
catch(Exception e)
{
e.printStackTrace();
}
return key;
}
}