狂奔 lion

          自強不息

          富客戶端技術中的JavaScript腳本國際化

          當前的富客戶端可以包含兩部分:分別為JSP頁面和通過富客戶端js組件(如extjs)渲染的組件化窗口頁。針對這兩部分分別做如下處理:

          對于JSP頁面的部分采用JSTL標準庫的fmt標簽,如通過:

          <fmt:message key="page.login.title"/>這樣的形式進行展現,其中message對應的文本在服務端配置,并在web.xml中配置資源文件的位置,也可以采用spring標簽,Structs標簽等多種機制。不過為了以后的程序修改兼容性,建議采用JSTL進行JSP頁面的國際化。

          對于JavaScript,考慮到為提高效率,因為是靜態資源,可以很方便的在一定周期內要在客戶端瀏覽器進行緩存,不同的瀏覽器會有不同的緩存機理,在IE中,js文件通過定義一定的過期期限,C:"Documents and Settings"用戶名"Local Settings"Temporary Internet Files下進行緩存,FirefoxC:"Documents and Settings"用戶名"Local Settings"Application Data"Mozilla"Firefox"Profiles"XXXXXXX.default"Cache,為了緩存而不是每次下載為了實現富客戶端而集成的很大的js,不能用動態的網頁來生成(即把JavaScript包裝為JSP頁面,最簡單的,把js擴展名改成jsp并利用jsp的機制做國際化)。因此,需要對JavaScript中國際化的內容通過變量單獨加載,舉例如下:

          var Message = function(){

                   this.title =’中文標題’;

                   ……

          };

          var msg = new Message();

          /********************************

          或:

          var msg = {

                   title : ‘中文標題’;

          };

          *********************************/

          new Ext.Window({  

               title : msg.title,          

               width : 265,              

               height : 140

          });

          其中msg對象的定義可以通過在另一個JavaScript文件中引用的本地化文件所定義,也可以通過AJAX返回JSON對象的形式來獲取或者動態地進行服務端生成。

          兩種方法的優缺點定義如下:

          方法

          缺點

          優點

          前臺主動定義

          會產生大量零碎的文件(MJavaScript文件需要對象N個語言的資源文件,總數M×N,如果把這些資源文件都放在一個JavaScript文件中定義,則對客戶端來說,要下載過多不必要的資源)

          資源定義非常靈活,可以保證只定義自己需要的資源,并且可以做到隨時更改其內容

          后臺自動獲取

          加重了服務器的負擔,需要用到AJAX或者類似dwr的服務端動態加載。具有一定的復雜性

          可以和后臺及JSP頁面共享同一個資源定義文件,并動態生成資源定義文件,減少了開發人員的負擔

          綜上,可以采取如下國際化方法:

          針對JavaScript文件的國際化,分成兩部分來進行:

          對于通用的文本定義,如:”確定返回等等,放在前臺的資源文件中,隨JavaScript文件一同加載,對于特殊的文本定義通過后臺自動獲取的形式來展現,這樣就可以結合兩種方法的優點。

          后臺實現的如下:

          按照命名規約定義頁面的文本元素,然后動態的生成一個如下的json對象:

          {

          messageName : messageValue

                   ……

          }

          然后前臺頁面JavaScript在加載時獲取這個json對象,并應用到頁面文本元素的定義中,如利用Extjs的使用方法:

          var msg = Ext.util.json.decode(jsonString); 或者服務器動態生成時就表述為var msg={…};的形式,并在頭文件指向動態的地址(類似dwr動態生成的機制),然后就可以通過msg.XXX來獲得文本定義了。文中涉及的代碼如下:

          import java.util.Enumeration;
          import java.util.HashMap;
          import java.util.Locale;
          import java.util.ResourceBundle;

          import net.sf.json.JSONObject;

          /**
           * 根據層次結構獲取到特定前綴的所有的資源名稱,并把它們放在一個JSON對象中返回,對于相同類型的資源請求進行緩存,
           * 不再動態生成新的內容。這個對象要納入到Spring的容器中進行管理,把bean的管理模式設置為單例模式就好,所以這里
           * 沒有提供對于類的單例封裝
           * 
           *  * 
          @author 楊一
           
          */


          public class HierarchicalMessage {
              
          /**資源對象的基礎名稱*/
              
          private String bundleName;
              
          /**特定組件所使用的前綴*/
              
          private String prefix;
              
          /**緩存對象用的哈希表*/
              
          private HashMap<String, JSONObject> cachingMap = new HashMap<String, JSONObject>();
              
              
          /**設置或注入對象的基礎名稱*/
              
          public void setBundleName(String bundleName) {
                  
          this.bundleName = bundleName;
              }


              
          /**設置或注入所使用的前綴*/
              
          public void setPrefix(String prefix) {
                  
          this.prefix = prefix;
              }


              
          /**根據注入的結果返回語言包,(某些情況下,請求的資源是一定的)*/
              
          public JSONObject getMessagesWithPrefix(Locale localeName){
                  
          return getMessagesWithPrefix(this.bundleName,this.prefix,localeName);
              }

              
              
          /**
               * 根據層次結構獲取到特定前綴的所有的資源名稱,并把它們放在一個JSON對象中返回
               * 
          */

              
          public JSONObject getMessagesWithPrefix(String bundleName, String prefix, Locale localeName){
                  JSONObject toReturn;
                  
          //拼接的緩存字符串的格式為:i18n/messages$page.login$zh_CN
                  String cachingString = new StringBuilder().append(bundleName).append("$").
                                          append(prefix).append(
          "$").append(localeName.toString()).toString();
                  toReturn 
          = cachingMap.get(cachingString);
                  
          if(toReturn != null){
                      
          return toReturn;
                  }

                  
                  toReturn 
          = new JSONObject();
                  
                  
          //此處無需緩存,因為Java核心庫會做這件工作
                  ResourceBundle rb = ResourceBundle.getBundle(bundleName, localeName);
                  
                  Enumeration
          <String> e = rb.getKeys();
                  String keyRef 
          = null;
                  String componentPrefix 
          = new StringBuilder().append(prefix).append(".").toString();
                  
          int shortNameStartIndex = prefix.length() + 1;
                  
          while(e.hasMoreElements()){
                      keyRef 
          = e.nextElement();
                      
          if(keyRef.startsWith(componentPrefix)){
                          toReturn.put(keyRef.substring(shortNameStartIndex), rb.getString(keyRef));
                      }

                  }

                  
                  cachingMap.put(cachingString, toReturn);
                  
                  
          return toReturn;
          }

          }

          import java.io.IOException;
          import java.io.PrintWriter;

          import javax.servlet.ServletException;
          import javax.servlet.http.HttpServlet;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;

          import org.springframework.web.context.WebApplicationContext;
          import org.springframework.web.context.support.WebApplicationContextUtils;

          import HierarchicalMessage;

          public class I18nServlet extends HttpServlet {
              
          /**
               * 動態生成一個用于國際化的JavaScript腳本
               * 
               * 
          @param request the request send by the client to the server
               * 
          @param response the response send by the server to the client
               * 
          @throws ServletException if an error occurred
               * 
          @throws IOException if an error occurred
               
          */

              
          public void doGet(HttpServletRequest request, HttpServletResponse response)
                      
          throws ServletException, IOException {
                  
                  response.setContentType(
          "application/json");
                  response.setCharacterEncoding(
          "UTF-8");
                  
                  PrintWriter out 
          = response.getWriter();
                  
                  HierarchicalMessage hm 
          = getHierarchicalMessage();
                  hm.setPrefix(
          new StringBuilder().append("page.").append(getBizId(request)).toString());
                  
          //此處從session中獲取用戶的登陸語言環境
                  String json = hm.getMessagesWithPrefix(request.getLocale()).toString();
                  
                  out.print(
          new StringBuilder().append("var msg=").append(json).append(";"));
                  out.close();
              }


              
          private HierarchicalMessage getHierarchicalMessage() {
                  WebApplicationContext wc 
          = WebApplicationContextUtils
                                               .getWebApplicationContext(getServletContext());
                  HierarchicalMessage hm 
          = (HierarchicalMessage)wc.getBean("msgBean");
                  
          return hm;
              }


              
          private String getBizId(HttpServletRequest request) {
                  StringBuffer urlString 
          = request.getRequestURL();
                  
          int start = urlString.lastIndexOf("/"+ 1;
                  
          int end = urlString.lastIndexOf(".");
                  
          return urlString.substring(start, end);
              }


          }


          Spring配置:
              
          <bean id="msgBean" class="HierarchicalMessage" scope="singleton">
                  
          <property name="bundleName">
                      
          <value>i18n/messages</value>
                  
          </property>
                  
          <property name="prefix">
                      
          <value>sys</value>
                  
          </property>
              
          </bean>

          Web.xml配置:
              
          <servlet>
                
          <servlet-name>I18nServlet</servlet-name>
                
          <servlet-class>I18nServlet</servlet-class>
              
          </servlet>
              
          <servlet-mapping>
                
          <servlet-name>I18nServlet</servlet-name>
                
          <url-pattern>/i18n/*</url-pattern>
              
          </servlet-mapping>

           

          使用方法:

          html頁面中先于功能js導入對應的語言js,名稱相同,路徑在/i18n/xxx.js

          同時在根classpath下的i18n/messages資源下定義page.xxx.xxx



           @2008 楊一. 版權所有. 保留所有權利

          posted on 2008-12-23 12:07 楊一 閱讀(2565) 評論(1)  編輯  收藏

          評論

          # re: 富客戶端技術中的JavaScript腳本國際化 2008-12-23 15:11 1444

          學習了
          文章不錯 看作者名字讓我想起了電視里爬出來貞子0_0  回復  更多評論   


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2008年12月>
          30123456
          78910111213
          14151617181920
          21222324252627
          28293031123
          45678910

          導航

          公告

          本人在blogjava上發表的文章及隨筆除特別聲明外均為原創或翻譯,作品受知識產權法保護并被授權遵從 知識分享協議:署名-非商業性使用-相同方式共享 歡迎轉載,請在轉載時注明作者姓名(楊一)及出處(www.aygfsteel.com/yangyi)
          /////////////////////////////////////////
          我的訪問者

          常用鏈接

          留言簿(5)

          隨筆分類(55)

          隨筆檔案(55)

          相冊

          Java

          其他技術

          生活

          最新隨筆

          搜索

          積分與排名

          最新評論

          閱讀排行榜

          評論排行榜

          自強不息


          用心 - 珍惜時間,勇于創造
          主站蜘蛛池模板: 柳州市| 汕头市| 阿荣旗| 临武县| 巴楚县| 报价| 奇台县| 淳安县| 根河市| 雅安市| 潜江市| 仙桃市| 静乐县| 天津市| 方正县| 股票| 山东省| 襄垣县| 阆中市| 香河县| 龙里县| 双城市| 南部县| 玉龙| 柘荣县| 古浪县| 康定县| 怀仁县| 浙江省| 弥渡县| 盐亭县| 榆林市| 商洛市| 贺兰县| 延吉市| 清水河县| 遵化市| 盐池县| 师宗县| 蕉岭县| 牡丹江市|