熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

Struts源碼研究 - Bean-Message標簽篇

2013-11-23 20:03:46  來源: Java開源技術 

  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對象的儲存)

From:http://tw.wingwit.com/Article/program/Java/ky/201311/27882.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.