`
yangyi
  • 浏览: 115333 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

富客户端技术中的JavaScript脚本国际化

    博客分类:
  • Java
阅读更多

当前的富客户端可以包含两部分:分别为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下进行缓存,Firefox是C:"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

 

分享到:
评论

相关推荐

    javascript 客户端常用脚本

    javascript 客户端常用脚本javascript 客户端常用脚本javascript 客户端常用脚本javascript 客户端常用脚本javascript 客户端常用脚本javascript 客户端常用脚本javascript 客户端常用脚本

    JavaScript富客户端编程

    JavaScript富客户端编程是一种技术,它允许开发者在用户浏览器上实现复杂的应用程序逻辑,提供与桌面应用类似的用户体验。这种编程方式极大地增强了网页的交互性和实时性,不再局限于简单的表单提交和页面刷新。...

    JavaScript客户端脚本语言

    JavaScript语言基础 JavaScript程序流程控制语句 JavaScript函数和事件处理程序 HTML文档对象模型 JavaScript内置的常用对象 用JavaScript脚本对HTML数据的的验证

    JavaScript脚本特效编程给力起飞

    JavaScript是一种基于对象和事件驱动并具有相对安全性的客户端脚本语言。同时也是一种广泛用于客户端Web开发的脚本语言,常用来给HTML网页添加动态功能,比如响应用户的各种操作。Javascript提供了丰富的运算功能,...

    利用客户端JavaScript脚本制作自测型教学网页.pdf

    【标题】:利用客户端JavaScript脚本制作自测型教学网页 【描述】:本文主要讨论如何利用客户端JavaScript脚本创建自测型教学网页,包括网页试卷的制作、JavaScript脚本的嵌入以及设置指向本地计算器的超链接。 ...

    WEB客户端技术 WEB客户端技术

    在提供的压缩包文件中,我们可以看到一系列有关Web客户端编程的知识点,如"ITJOB_TP"系列可能是教学课件,涵盖了不同阶段的Web技术学习;"WEB客户端编程知识要点.ppt"可能是对核心概念的总结;"chapter1-3课堂案例...

    一个基于ASP.NET 的js客户端处理技术JavaScript Tips 之一

    以上只是基于ASP.NET的JavaScript客户端处理技术的一部分,实际开发中还有更多细节需要关注,例如SEO优化、无障碍访问性、跨域问题等。KaramasoftJavaScriptTips-Part1可能包含更具体的示例和实践,建议深入学习,以...

    客户端日期选择的脚本

    客户端日期选择脚本是网页应用中常见的一种交互元素,它允许用户在不离开当前页面的情况下选取特定日期。这种脚本通常使用JavaScript实现,因为它是一种在客户端运行的编程语言,能够实时更新网页内容,提高用户体验...

    第4章__客户端脚本语言_java客户端脚本语言_

    java客户端脚本语言。JavaScript是一种嵌入HTML的脚本语言,它不需要编译,在客户端可以通过浏览器解释执行。JavaScript具有跨平台、基于对象和事件驱动的特点,同时它也具有一定的安全性。

    浅谈关于JavaScript脚本语言的学习.pdf

    1. 客户端数据验证:JavaScript脚本可以直接对用户操作做出响应,对客户端数据进行验证,不需要经过Web服务器程序处理,节约了客户端与服务器之间的交互时间。 2. 动态网页:JavaScript脚本可以使静态的HTML网页...

    asp脚本及javascript网页开发脚本

    在学习过程中,可以先从ASP中文帮助手册开始,理解服务器端脚本的基本概念和工作原理,然后通过JavaScript 5深入学习客户端脚本,掌握网页动态化和用户交互的实现方法。两者结合,将有助于提升你在网页开发领域的...

    网页javascript脚本语言提取器

    "网页JavaScript脚本语言提取器"是一个工具,专门设计用于从网页中抓取并分析JavaScript代码,这在进行网页分析、调试或者学习JavaScript时非常有用。 1. **JavaScript的基本概念**: - JavaScript是一种轻量级的...

    客户端脚本验证总结

    客户端脚本验证是Web开发中不可或缺的一环,它主要用于在用户与服务器交互的前端阶段确保数据的正确性和安全性。在JavaScript这一强大的客户端编程语言的支持下,我们可以实现多种验证策略,提高用户体验并减轻...

    javascript客户端图片预览脚本

    javascript客户端图片预览,支持火狐、ie、谷歌(chrome)

    浅析页面中Java与JavaScript脚本的区别.pdf

    浅析页面中Java与JavaScript脚本的区别 Java 与 JavaScript 脚本是两种不同的编程语言,它们在 Web 开发中扮演着重要的角色。虽然它们都可以嵌入到 HTML 页面中,但是它们的表示方式、执行过程和应用场景都是不...

    如何在浏览器中运行JavaScript脚本:深入解析与实践指南

    本文将详细介绍如何在浏览器中运行JavaScript脚本,包括基本的语法、运行环境、以及实际的代码示例。 JavaScript是一种强大的语言,它为Web开发带来了无限的可能性。通过了解如何在浏览器中运行JavaScript脚本,你...

    一个基于ASP.NET 的js客户端处理技术JavaScript Tips 之二。

    在ASP.NET开发中,JavaScript作为客户端脚本语言,发挥着至关重要的作用,特别是在增强用户体验、交互性和实时数据处理方面。本文将围绕"JavaScript Tips 之二"这一主题,深入探讨如何在ASP.NET环境中有效地利用...

    客户端技术资料 很多

    客户端技术在IT行业中占据着至关重要的地位,尤其是对于构建交互性强、用户体验良好的Web应用程序来说。这份压缩包包含了一系列关于客户端技术的参考资料,如HTML、JavaScript、CSS以及与它们相关的实践应用。下面,...

    加载JavaScript脚本的包

    这就是`js jar jwr`标签所指的场景,它涉及到Java运行时环境中如何加载和执行JavaScript脚本。 1. **Nashorn JavaScript引擎**: 在Java 8之前,Java提供了Nashorn JavaScript引擎,这是一个内置的JavaScript解释...

Global site tag (gtag.js) - Google Analytics