利用Ajax与ExtJS改善用户体验

2011-03-14 05:12秦姣华,袁智威,王振
电子设计工程 2011年10期
关键词:服务器端浏览器网页

在网络需求越来越多的时代,传统的Web1.0技术由于其同步交互方式,带来了很大网络流量以及很差的用户体验,以Wiki,google Map等为代表的Web2.0技术以及RIA的应用极大地提高了网络性能和用户体验,成为了Web应用领域的主力军。在实现高用户体验及时交互方面,有5种技术可供选择:1)Flex和OpenLaszlo;2)IBM®WorkplaceTMManaged Client和IBM Lotus®Expeditor;3)Faces Client Com-ponents;4)Ajax;5)HTML[1],考虑到开发难度以及具体C2C交易平台后台系统的特点,选择Ajax技术。Ajax综合了以前DHTML技术,通过XMLRequest出色地完成了异步交互功能,带来了系统性能的很大提升。然而纯Ajax代码相当复杂,开发和调试都比较麻烦,同时需要前端美工和后台程序员很好的合作,才能构建出好的Ajax应用。幸运的是,ExtJS提供了很好的解决方案,程序员不需要精通DHTML就可以轻易地构建一套高用户体验界面,同时ExtJS是基于JavaScript的,对Ajax有很好的支持。因而,后台程序员就能脱离前台美工来独立构建高用户体验的Web系统。

1Ajax技术与ExtJS框架概述1.1Ajax原理

作为DHTML技术的升级,Ajax大部分沿用了以前的老技术,它是将一部分业务逻辑转移到客户端,使得客户端不仅仅是个页面,而且有强大的业务逻辑支撑着,一般是用JavaScript实现的,html与css负责界面的实现。从这方面讲也类似于C/S结构,不过Ajax是尽可能的实现C/S结构高交互能力效果的同时又保持B/S结构的平台无关性。

浏览器在执行任务时会自动装载Ajax引擎[2]。具体过程:浏览器发送请求到服务器,服务器响应请求,把页面数据(包括html,js,css文件)发送到浏览器,浏览器解析成网页,可以将其看作是一个小型的客户端程序,用户可以像使用桌面应用程序一样来操作页面。当用户点击页面上某一按钮或其他,浏览器端便会相应产生一个事件,浏览器端控制器感应该事件,而调用相应的Model来实现相应的业务逻辑。Model利用XMLHTTPReader发送请求到服务器,服务器响应请求,回复相应的数据到浏览器端,然后XMLHttpReader回调callback(),接收并解析数据。一般回复的数据为txt,json或xml。最后Model利用DOM(Document Object Model,文档对象模型)找到或创建页面上相应的元素,将解析后的数据加载到相应的元素上,View将数据显示在页面,图1是Ajax的调用示意图。

图1 Ajax调用示意图Fig.1Schematic diagram of calling Ajax

基于Ajax的客户端其实也是一个类似于服务器端的MVC实现。与传统Web1.0技术相比,可以看出Ajax摒弃了整个页面刷新式的交互,而是采用异步事件处理的方式来请求服务器端的关键数据(即不带html标记的数据),拥有自身的业务逻辑,从而大大减轻网络压力和服务器的压力。

1.2 ExtJS概述

ExtJS发源于YUI,最先由Jack Slocum开发,是采用OOP设计思想建立类库与后台语言无关的JavaScript框架[3],它将OOP发挥到了极致。然而ExtJS不仅仅是个JavaScript框架,它可以独立于其他JavaScript框架通过Adapter(适配器)[4]。对于后台程序员而言,不需要很深的网页开发功底,就可以很快地开发出用户体验很高的类似桌面应用的界面,一方面减少了与美工的交流,自己来开发客户端界面,另一方面开发出来的界面交互能力很强,能够很好地与后端服务器结合。

2 三农商城后台管理系统(OA型)实现技术

2.1 整体布局

ExtJS提供了Ext.ViewPort视图类,它可以根据layout配置,实现不同的布局风格。在开发三农商城后台管理系统时,主界面采取border(边界)布局方式,整体布局见图2。它根据Ext.layout.BorderLayout.Region类定义的东西南北中5个区域来布局每一个区域,每个区域为一个panel面板类的实例。同时ViewPort会自动充斥整个浏览器。Ext提供了Ext.onReady(fn)方法,在页面装载完毕后,自动运行。与Window.onLoad()不同的是,Ext.onReady(fn)是在页面装载完毕后,而不是等到所有的图片和flash等装载完毕后执行,这样相对于传统的Window.onLoad(),有更高的响应速度。

图2 整体布局效果图Fig.2The overall layout diagram

代码如下:

Ext.onReady(function(){var mainViewPort=new Ext.ViewPort({renderTo:Ext.getBody(),layout:“border”,items:[{xtype:"panel",title:"顶部标题栏",region:"north"},{/*略*/},{/*略*/},{/*略*/},{/*略*/},{/*略*/}]})

});

2.2 动态树的实现

Ext提供了对树的支持,包括TreePanel树面板,TreeNode树节点,TreeLoader树加载器。利用树,可以很好的表示数据的层次结构。如创建动态类别树结构。通过TreePanel创建一个面板,每一个类别即是一个节点,用TreeLoader异步请求服务器,得到数据,然后解析显示到页面上。一般数据传输的格式有xml和Json两种,由于Json的数据量比较小,而且是JavaScript固有的对象支持格式,大多都使用Json的方式。下面以基于J2EE的三农商城开发中省市县动态树为例介绍动态树的实现技术,图3是省市县动态树效果图。

图3 Tree效果图Fig.3Tree diagram

基于J2EE的省市县动态树客户端开发代码如下:Ext.onReady(function(){

var loader=new Ext.tree.TreeLoader({url:"manage/categoryMng!getTree"//请求的地址});

//在节点内容加载前执行

loader.on("beforeload",function(loader,node){loader.baseParams.id=node.id;//向服务器端传递参数});

var areaTreePanel=new Ext.tree.TreePanel({id:"all",title:"类别",renderTo:Ext.getBody(),root:"all",loader:loader});

});

在服务器端,采用Struts2.1表示层框架,为了使其能方便地支持Json,使用json-plugin插件。服务器端Action代码如下:

public class CategoryMng extends ActionSupport

{@Resource CategoryService categoryServiceBean;

private List<Node>nodes=new ArrayList<Node>();

public String getTree()throws Exception

{String id=ServletActionContext.getRequest().getParameter("id");

Set<Category>categorys=categoryServiceBean.get(id).getChildren();

//通过DAO获取子类别

nodes=categoryServiceBean.toNodes(categorys);//转化为节点类

return super.SUCCESS;

}

public List<Node>getNodes()

{return nodes;}

}

节点类代码如下:

public class Node

{public String id;//序号

public String url;//链接地址

public boolean leaf;//是否是叶子节点

/*set和get方法略*/

}

struts.xml文件配置如下:

<packagename="manage"namespace="/manage"extends="json-default">

<action name="categoryMng"class="com.hncu.web.action.CategoryMng">

<result type="json">

<param name="root">nodes</param>

</result>

</action>

</package>

2.3 网页动态加载

在传统的DHTML技术中,网页动态加载一般都是通过iframe嵌套加入网页中,这样每次加载都要重新引入js和css文件,严重情况下,一个页面层层迭代嵌入了6、7个iframe,极大地增加了网络压力和客户端CPU开销。ExtJS提供了panel动态加载网页的功能,可以在不重新加载js和css文件的情况下,将html嵌入指定的div中。在ExtJS3.2中,改进了动态内嵌入网页的功能,增加了对JavaScript代码的支持,将JavaScript作为脚本解释型语言的特性发挥到极致。

Ext.Window动态加载实现代码如下:

var win=Ext.Window({/*略*/})

win.load({url:"manage/productList.action",//请求的地址

params:{//带入参数

categoryId:1,pageSize:10

},script:true

});

2.4 实时更新

在B/S结构中,浏览器与服务器之间的交互方式是单方面的,即浏览器主动请求服务器,然后服务器与浏览器之间建立TCP/IP连接,并且两者之间的会话是无状态的。尽管真正意义上的双向交互是不可能的,但是可以利用Ajax技术让浏览器定时自动向服务器发出请求,达到实时更新的效果。下面以三农商城系统消息实时提醒为例来讨论实时更新的实现。

客户端代码如下:

var htmlContent;

function ajaxInterval()

{Ext.Ajax.request({url:"updateAction",//请求的地址

method:'GET',success:function(response)

{//利用JSON进行编码,返回JavaScript的原生类类型

var obj=Ext.util.JSON.decode(response.responseText);

for(var i=0;i<obj.length();i++)

{/*把obj组装成html代码赋值给htmlContent*/}

}

});

}//设置定时器

window.setInterval("ajaxRequest()",3000);

/**将htmlContent按照表现逻辑显示到页面上**/

系统通过window.setInterval()函数来定时执行ajaxRequest()方法,从而动态请求服务器,然后将返回的数据用JSON进行解析后,显示到页面,从而达到实时更新消息的效果。服务器端代码JSON组装代码参考2.2。

2.5 状态保存

为了避免用户在数据输入时遇到断电、网络中断等意外时造成数据丢失,减低工作效率等问题,因而需要采用自动保存机制。自动保存机制主要有两种方法,一种是及时保存到服务器,另一种是把数据及时保存到本地机器。第一种是定时把数据发送到服务器,让服务器持久化到数据库中,显然这种方式代价很大,增加了Web服务器和数据库服务器的压力;第二种是先保存到本地机器cookie中,待故障恢复后自动发送到服务器持久化。

TextArea状态保存代码实现如下[5]:

StatefulTextArea=Ext.extend(Ext.form.TextArea,{stateEvents:['change'],//设置状态监听事件

getState:function(){return{text:this.value//设置保存的数据为TextArea的值}},

applyState:function(state){this.setValue(state.text);//设置状态应用事件}

});

//设置状态管理器提供者为Cookie

Ext.state.Manager.setProvider(new Ext.state.CookieProvider({

expires:new Date(new Date().getTime()+(1000*60*60*24*30))//保存一个月}));

3 性能调优

3.1 定制和动态加载文件

在ExtJS3.2中,单extjs-all.js文件就有600多K,按1Mb/s的网速算,单加载这个文件就要耗费大约5 s,使得响应时间增加了很多。其实ExtJS中的js文件是可以定制的,可以根据自己的需要来导入关联的js文件,而没必要一次性导入所有的库。另一方面,即使要用到某个js文件,如果不是马上要用到的话,也没必要一开始就加载进去,可以采用延迟加载的原则,用到时再加载。

3.2 数据压缩

造成浏览器与服务器之间传输量大的很大一部分原因是由于传输数据中存在大量的空格等无用字符,因此,采用GZIP做为http压缩工具,对静态文件html,javaScript,css,Text以及动态JSP,Servlet输出的网页进行压缩,从而减少网络流量。tomcat容器下GZIP压缩配置参考文献[6]。

3.3 缓存页面

缓存技术已经应用到计算机领域的各个方面,在J2EE方面,数据库,业务逻辑层,表现层都可以设置缓存。它通过对大量访问同一种资源进行保存,而减少不必要的服务器负载压力,达到提高效率的目的。页面缓存是通过html提供的meta标签的http-equiv属性来实现。包括:

1)<meta http-equiv="Expires"content="">可以用于设定网页到期时间,一旦过期则必须到服务器上重新调用,必须使用GMT时间格式;

2)<meta http-equiv="Pragma"content="no-cache|nostore|max-age|max-state|min-fresh|onif-cached">是用于设定禁止浏览器从本地机缓存中调阅页面内容,设定后一旦离开网页就无法从Cache中再调出;

3)<meta http-equiv="cache-contro"content="no-cache|no-store|max-age|max-state|min-fresh|onif-cached">指定和响应遵循的缓存机制,它不会影响另一个消息处理的缓存过程。

在页面缓存方面,OSCache给我们提供了一个良好的框架,通过这个工具,可以自由的选择缓存区域(硬盘,内存),缓存范围(页面级缓存和部分页面内容缓存)。同时也提供了丰富的标签,方便了JSP的配置。详细配置参考文献[7]。

4 结束语

Ajax作为Web2.0的核心技术之一,带来了Web用户体验革命性的改变。ExtJS作为Ajax的客户端UI框架,很大程度上减少了系统开发成本,同时又保证了系统的美化以及页面响应速度。利用Ajax+ExtJS组合,有效避开了传统B/S结构用户体验差的特点,又具有了C/S结构的强交互能力,同时还具有很好的可移植性和可维护性。作为RIA应用的新生儿,ExtJS将走得更远。

[1]宋转玲,刘海行,代亮,等.基于ExtJS开发的海洋科学数据共享平台[J].海洋科学,2010,34(2):4-9.SONG Zhuan-ling,LIU Hai-xing,DAI Liang,et al.Qingdao oceanic data service system based on ExtJS[J].Marine Sciences,2010,34(2):4-9.

[2]郑玲,蒲强,刘晓建.基于AJAX技术构建汽轮机组远程故障监测系统的设计与研究[J].中国电力教育,2008,(S2):353-355.ZHENG Ling,PU Qiang,LIU Xiao-jian.Design and research of the turbine remote fault monitoring system based on AJAX[J].China Electric Power Educationm,2008,(S2):353-355.[3]雷镭,陈俊.基于ExtJS及Pushlet实现Web及时交流[J].软件导刊,2010,9(2):118-120.LEI Lei,CHEN Jun.Implementation of Web communication by ExtJS and pushlet[J].Software Guide,2010,9(2):118-120.

[4]Frederick S,Ramsay C,Steve Cutter Blades.Learning ExtJS[M].Packt Publishing Ltd.,2008:10-21.

[5]ExtJS3.2 document[EB/OL].(2010-4-12)[2010-10-1].http://dev.sencha.com/deploy/dev/docs/.

[6]Apache Tomcat6.0 document[EB/OL].(2010-3-24)[2010-10-1].http://fangrn.javaeye.com/blog/623339.

[7]Opensymphony[EB/OL].(2009-3-6)[2011-3-1].http://www.opensymphony.com/oscache/wiki/CacheFilter.html.

猜你喜欢
服务器端浏览器网页
Linux环境下基于Socket的数据传输软件设计
反浏览器指纹追踪
基于CSS的网页导航栏的设计
基于HTML5静态网页设计
浅析异步通信层的架构在ASP.NET 程序中的应用
基于URL和网页类型的网页信息采集研究
基于Qt的安全即时通讯软件服务器端设计
环球浏览器
网页制作在英语教学中的应用
网页防篡改中分布式文件同步复制系统