最近一段时间,一直在研究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; } }