Struts中非常常用的有这样的一个标签
<bean:message key=welcometitle/>
众所周知这个标签做的事情是这样的
访问在strutsconfigxml中定义的资源文件一般是applicationproperties一般是这样定义的
<messageresources parameter=resourcesapplication/>
根据以上的定义Struts将到WEBINF/classes/resource/下去找applicationproperties文件这是从以上配置信息的表面上看起来是这样但通过查看Struts的源码可以看到如下的代码在orgapachestrutsutilPropertyMessageResources类中有如下的代码
通过这段代码可以看到
Aproperties扩展名是写死在代码中的所以资源文件必须使用这个扩展名
BStruts并不是单纯去寻找applicationproperties文件而是首先找到application赋给name变量然后加上下划线_然后再加上localeKey(如zhen)然后再加上properties
C确定了文件名之后Struts使用了ClassLoader类的getResourceAsStream方法得到了一个InputStream
D然后Struts使用了javautilProperties类的load方法将资源文件中的所有资源读出放到了一个HashMap里面
E然后Struts就可以根据key值取出不同的message给前台了
// Set up to load the property resource for this locale key if we can
String name = configreplace( /);
if (localeKeylength() > ) {
name += _ + localeKey;
}
name += properties;
InputStream is = null;
Properties props = new Properties();
// Load the specified property resource
if (logisTraceEnabled()) {
logtrace( Loading resource + name + );
}
ClassLoader classLoader = ThreadcurrentThread()getContextClassLoader();
if (classLoader == null) {
classLoader = thisgetClass()getClassLoader();
}
is = classLoadergetResourceAsStream(name);
if (is != null) {
try {
propsload(is);
} catch (IOException e) {
logerror(loadLocale() e);
} finally {
try {
isclose();
} catch (IOException e) {
logerror(loadLocale() e);
}
}
}
D步骤中的load方法可以参看JDK的帮助文档load方法要求这个资源文件必须以ISO编码进行书写方能正确解析 所以如果我们在资源文件中写入了中文并在运行时出现了中文编码问题(?出现)那么只需确认您的资源文件是否是以ISO为编码进行书写的即可
另外Struts在查找资源文件时首先是按照如上的描述进行$Filename_$Localeproperties文件的查找如果他找不到那么他就会用默认的$Filenameproperties来找如果还找不到那就报错了这个Struts的查找顺序并不是我的杜撰有如下Struts源码为证(这个方法是PropertyMessageResourcesjava中的)
public String getMessage(Locale locale String key) {
if (logisDebugEnabled()) {
logdebug(getMessage( + locale + + key + ));
}
// Initialize variables we will require
String localeKey = localeKey(locale);
String originalKey = messageKey(localeKey key);
String messageKey = null;
String message = null;
int underscore = ;
boolean addIt = false; // Add if not found under the original key
// Loop from specific to general Locales looking for this message
while (true) {
// Load this Locales messages if we have not done so yet
loadLocale(localeKey);
// Check if we have this key for the current locale key
messageKey = messageKey(localeKey key);
synchronized (messages) {
message = (String) messagesget(messageKey);
if (message != null) {
if (addIt) {
messagesput(originalKey message);
}
return (message);
}
}
// Strip trailing modifiers to try a more general locale key
addIt = true;
underscore = localeKeylastIndexOf(_);
if (underscore < ) {
break;
}
localeKey = localeKeysubstring( underscore);
}
// Try the default locale if the current locale is different
if (!defaultLocaleequals(locale)) {
localeKey = localeKey(defaultLocale);
messageKey = messageKey(localeKey key);
loadLocale(localeKey);
synchronized (messages) {
message = (String) messagesget(messageKey);
if (message != null) {
messagesput(originalKey message);
return (message);
}
}
}
// As a last resort try the default Locale
这里可以看到Struts最后将localeKey赋空
这样资源文件就是$Filenameproperties了
localeKey = ;
messageKey = messageKey(localeKey key);
loadLocale这个方法将读取资源文件填入HashMap
这个方法的代码在上面已经列出来了
loadLocale(localeKey);
synchronized (messages) {
message = (String) messagesget(messageKey);
if (message != null) {
messagesput(originalKey message);
return (message);
}
}
// Return an appropriate error indication
if (returnNull) {
return (null);
} else {
return (??? + messageKey(locale key) + ???);
}
}
至于这个$Locale的值是多少通过很长时间的查找之后发现了这样一些代码
在orgapachestrutsutilRequestUtils类中的多行左右有这样一个方法
public static Locale getUserLocale(HttpServletRequest request String locale) {
Locale userLocale = null;
HttpSession session = requestgetSession(false);
if (locale == null) {
locale = GlobalsLOCALE_KEY; //这个值是orgapachestrutsactionLOCALE
}
// Only check session if sessions are enabled
if (session != null) {
userLocale = (Locale) sessiongetAttribute(locale);
}
if (userLocale == null) {
// Returns Locale based on AcceptLanguage header or the server default
userLocale = requestgetLocale();
}
return userLocale;
}
可以看出Struts将Locale的实例对象放到了session中但是他什么时候将这个对象放到session里面的尚未找到(很多配置在ActionServlet中读取并储存的因为这个类是第一个启动的类但这个类中没发现Locale对象的储存)