浅论web快速应用开发框架的研究

浅论web快速应用开发框架的研究

ID:35128552

大小:2.96 MB

页数:94页

时间:2019-03-19

上传者:U-24835
浅论web快速应用开发框架的研究_第1页
浅论web快速应用开发框架的研究_第2页
浅论web快速应用开发框架的研究_第3页
浅论web快速应用开发框架的研究_第4页
浅论web快速应用开发框架的研究_第5页
资源描述:

《浅论web快速应用开发框架的研究》由会员上传分享,免费在线阅读,更多相关内容在学术论文-天天文库

WEB快速应用开发框架的研究重庆大学硕士学位论文学生姓名:秦长春指导教师:邢永康副教授专业:计算机软件与理论学科门类:工学重庆大学计算机学院二OO八年四月 ResearchofWebRapidApplicationDevelopmentFrameworkAThesisSubmittedtoChongqingUniversityinPartialFulfillmentoftheRequirementfortheDegreeofMasterofEngineeringbyQinChangChunSupervisor:AssociateProf.XingYongKangMajor:ComputerSoftwareandTheoryCollegeofComputerofChongqingUniversity,Chongqing,ChinaApril2008 中文摘要摘要随着WEB应用的迅速发展,WEB应用开发中的矛盾也日渐突起,请求响应的无状态、页面的频繁跳转以及复杂的逻辑转换等困扰着众多开发人员,他们开始怀念C/S模式下的快速应用开发(RapidApplicationDevelopment简称RAD)编程环境,希望WEB开发也能自由的拖放可重用的可视化控件来定制自己的界面,并对这些控件进行事件机制编程,开发人员不用再关注页面的跳转,所有的变化只是控件的数量、位置不同而已,其逻辑层清晰可见。为提高WEB开发的效率,需要一些可以继承RAD开发优点的开发框架。为此,本文研究的主要目的是如何在WEB应用下实现RAD并实现一个WEBRAD的开发框架。首先,对传统C/S模式下RAD的进行分析,总结出RAD的常用设计模式和特点,结合WEB应用,分析如何在WEB下实现RAD;然后分析RAD中的控件模型,实现WEB请求响应的无状态到状态管理的研究,建立WEB下控件模型;随后对RAD中重要的事件机制分析,通过事件驱动模型的原理和WEB应用开发的原理,建立WEB开发下的事件机制;最后基于JSF框架上使用Eclipse的插件系统建立WEBRAD的开发框架,通过SWT/JFace和插件扩展点机制构建系统界面和相关插件集模块,再使用GEF图形编辑框架构建页面模型编辑器,使用EMF框架的JET实现部分代码框架的自动生成与管理,最后使用Hibernate开源框架实现数据的持久化。本文的主要特点是:一、分析研究RAD的原理并探讨WEB开发下建立RAD的方法;二、深入研究控件模型和事件驱动模型在WEB中建立的过程;三、使用开源的可扩展插件机制的Eclipse和其它开源的框架建立一个WEB快速应用开发框架。目前,快速开发框架已经能够进行实验性运行且效果良好,达到了预期的学习和实践目的,为进一步的研究奠定了坚实基础。最后对开发框架发展的未来可能会向RAD、开源和可扩展这三个方向发展进行了预测。关键词:快速应用开发,事件机制,Eclipse,框架I 重庆大学硕士学位论文II 英文摘要ABSTRACTWiththerapiddevelopmentofWEBapplications,thecontradictionsintheWEBapplicationdevelopmentprocessesareincreased.Statelessofrequestandresponse,frequentjumppagesandcomplexlogicconversion,etc.aretroublingmanydevelopers,whobegintomisstherapidapplicationdevelopment(RapidApplicationDevelopmentasRAD)programmingenvironmentintheC/Smodel.Moreover,theyhopethatWEBdevelopmentcanprovidevisualcontrolsthatcanbeofreusabledraganddroptocustomizetheirinterface,andthesecontrolscanberealizedevent-drivenprogrammingmodel.Developersdonothavetoconcernpagesofjump.Thechangesareonlyinthenumberofcontrolsandpositionsofcontrols.Thelogicofthesecontrolsisvisibleclearly.InordertoenhanceB/Smodeldevelopmentmoreefficient,somedevelopmentframeworkswhichcouldinheritthemeritsoftheC/Smodeldevelopmentareneededurgently.Therefore,themainpurposeofthispaperishowtorealizeRADWEBapplicationandaWEBRADdevelopmentframework.Firstofall,thetraditionalC/SunderthemodeofRADshouldbeanalyzed,summarizingtheRAD'scommondesignpatternsandcharacteristicsofWEBapplication,analyzinghowtoachieveWEBRAD;Secondly,thecontrolmodelofRADwillbeanalyzed,achievingtheresponseandrequestofWEBstatelesstostatemanagement,theestablishmentofWEBcontrolmodel.Meanwhile,RADexpansionJSFcomponentsareexpandedfortheestablishmentpreparationofRADcontrolslibrary.Thirdly,ananalysisisdonetotheveryimportantevent-driventhroughtheprinciplesofevent-drivenmodelandtheWEBapplicationdevelopmentprinciple.TheeventmechanismundertheWEBdevelopmentmechanismisestablished.Fourthly,basedontheJSFframework,WEBRADdevelopmentframeworkwillbebuiltbyusingtheplug-insystemofEclipse.Thesysteminterfaceandplug-insrelatedmodulewillberealizedbyusingSWT/JFaceandplug-inadd-onpointmechanism.ThenGEFgraphicseditorframeworkwillbeusedtobuildthepagemodeleditor,usingtheEMFframeworkJETtorealizethecodegeneratedautomaticallyandmanagement.Finally,thedatapersistencecanberealizedbyutilizingtheopensourceFrameworkofHibernate.Therearethreemainfeaturesofthispaper.First,analyzingtheprinciplesofRADWEBdevelopmentandexploringtheestablishmentoftheRAD;Second,in-depthstudyIII 重庆大学硕士学位论文controlmodelandtheevent-drivenmodelofhowtocreateaWEBtheprocess;Third,realizingaWEBRADframeworkbasedonopensourceExtensionofthemechanismofEclipseandotheropen-sourceframework.Atpresent,therapiddevelopmentframeworkhasbeenabletoconductexperimentaloperationandperformingwell,achievingtheperspectiveobjectiveofstudyandpracticeandlayingasolidfoundationforfurtherstudy.Finally,thedirectionsofthefutureframeworkdevelopmentareforecasted:RAD,opensourceandscalable.Keywords:RAD,Eventmechanism,Eclipse,FrameworkIV 目录目录中文摘要..........................................................................................................................................I英文摘要.......................................................................................................................................III1绪论......................................................................................................................................11.1本文研究背景及意义...........................................................................................................11.1.1研究背景...................................................................................................................11.1.2研究意义...................................................................................................................21.2本文研究的目的和研究内容...............................................................................................31.2.1本文研究的目的.......................................................................................................31.2.2本文研究的内容.......................................................................................................31.3本文的组织结构...................................................................................................................42WEBRAD分析.................................................................................................................52.1引言.......................................................................................................................................52.2RAD的常用设计模式.........................................................................................................62.2.1资源窗体...................................................................................................................62.2.2数据敏感控件...........................................................................................................62.2.3MVC分层结构.........................................................................................................72.2.4主框架机制...............................................................................................................72.2.5逻辑组件化...............................................................................................................72.2.6自定义事件...............................................................................................................72.3RAD工具的特点.................................................................................................................82.3.1面向对象...................................................................................................................82.3.2可视化控件...............................................................................................................82.3.3事件驱动模型...........................................................................................................82.3.4代码的自动生成.......................................................................................................92.4WEB快速应用开发.............................................................................................................92.4.1C/S与B/S架构........................................................................................................92.4.2WEBRAD分析......................................................................................................133建立WEB控件模型.....................................................................................................173.1控件模型.............................................................................................................................173.1.1控件的三大要素.....................................................................................................173.1.2控件生命周期.........................................................................................................18V 重庆大学硕士学位论文3.2建立WEB控件模型........................................................................................................193.2.1HTTP请求—响应模型..........................................................................................193.2.2WEB开发模型.......................................................................................................203.2.3WEB控件模型.......................................................................................................224建立WEB事件驱动模型..........................................................................................254.1事件机制.............................................................................................................................254.1.1事件驱动概念模型.................................................................................................264.1.2事件驱动的开发模型.............................................................................................284.2建立WEB事件驱动模型................................................................................................314.2.1WEB状态管理.......................................................................................................314.2.2WEB事件模型.......................................................................................................324.2.3WEB事件分类.......................................................................................................355建立WEBRAD开发环境........................................................................................395.1引言.....................................................................................................................................395.1.1Eclipse概述...........................................................................................................395.1.2GEF概述................................................................................................................405.1.3JSF概述..................................................................................................................415.1.4扩充控件库.............................................................................................................425.2系统分析与设计.................................................................................................................465.2.1开发环境功能分析.................................................................................................465.2.2开发环境结构设计.................................................................................................475.2.3开发环境.................................................................................................................485.3建立WEBRAD开发环境................................................................................................495.3.1RAD环境界面的实现...........................................................................................505.3.2页面编辑器的实现.................................................................................................535.3.3数据持久化的实现.................................................................................................625.3.4生成与部署模块的实现.........................................................................................626WEBRAD应用实例....................................................................................................676.1具体实现.............................................................................................................................676.2开发步骤.............................................................................................................................686.2.1建立应用.................................................................................................................686.2.2持久化配置.............................................................................................................686.2.3定制界面.................................................................................................................696.2.4事件开发.................................................................................................................70VI 目录6.2.5部署并运行WEB应用..........................................................................................706.3框架开发环境评价.............................................................................................................717结论与展望.........................................................................................................................737.1研究的成果.........................................................................................................................737.2需进一步完善的问题.........................................................................................................737.3展望.....................................................................................................................................74致谢.......................................................................................................................................75参考文献.......................................................................................................................................77附录.......................................................................................................................................81VII 重庆大学硕士学位论文VIII 1绪论1绪论1.1本文研究背景及意义1.1.1研究背景快速应用开发(RapidApplicationDevelopment简称RAD),是JamesMartin[1]于上世纪80年代中期在DuPont工作时提出了这个概念。RAD是一个线性顺序[2]的软件开发模型,强调极短的开发周期。RAD模型是线性顺序模型的一个―高速‖[3]变种,通过使用可复用构件,采用基于构件的建造方法获得了快速开发。如果正确地理解了需求,且约束了项目范围,利用这种模型使得一个开发组能够在很短[4,5]时间内(如60到90天)创建出功能完善的信息系统,并由此出现了许多优秀的RAD开发工具,如VB、Delphi等开发工具。应用程序开发可分为两大类型:一类是桌面应用程序的开发,也就是C/S(Client/Server的简称,客户/服务器)模式下的开发;一类是WEB应用程序的开发,也就是B/S(Browser/Server的简称,浏览器/服务器)模式下的开发。快速应用开发方法曾经在C/S结构软件开发中风靡一时。这得益于众多RAD开发工具的产生,微软公司的VisualBasic(VB),Sybase公司的PowerBuilder(PB),Borland公司的[6]Delphi等全球许多著名的公司为RAD开发工具做出了重大贡献。如果你用过诸如VB,PB或DEPHI的快速应用开发工具,你会真正感觉到开发应用程序的高效性和便利性,开发人员只需要简单地拖放一些用户界面控件或其它的组件,每个控件或组件都有一些对应的属性和方法,然后对这些控件的动作编写程序,即事件响应过程。使用RAD工具可以快速的所见即所得的使用可视化可重用控件以及事件响应,通过少量的代码甚至不用开发人员写代码(这些代码在后台通过一定的生成机制自动生成)来实现应用程序开发,大大提高了软件开发的效率,有效的减短了开发的周期。在B/S结构下Web应用程序无论是在工作原理还是在开发模式上都与桌面应用程序有很大的区别。从工作原理上讲,在Web应用中用户使用浏览器基于HTTP协议向服务器发送请求,Web服务器接受请求后创建Web应用程序进程或者线程,并将执行结果以标准的HTML/XML文本格式返回给客户端浏览器。在开发模式上,桌面应用程序是基于事件驱动的Windows编程,而Web应用则是基于无状态Web协议的浏览器与服务器的超文本传递。可视化Windows应用程序开发工具在90年代初就已经有较成熟的产品出现,而可视化Web应用程序开发工具最近才出现。正因两者的区别较大,很多桌面应用程序开发人员由于己经适应了开发1 重庆大学硕士学位论文Windows应用程序的可视化开发工具,很难实现编程思路和习惯的改变而转向Web应用程序的开发。[7][8]传统的Web应用程序开发技术例如CGI、ISAPI、服务器端脚本(例如ASP)等都存在诸多缺点。CGI被认为是早期开发Web应用程序的规范,可以使用多种编程语言来开发。对于CGI技术,每个应用程序组件是一个独立的程序。客户端每向服务器发送一个请求,服务器都会创建一个新进程来处理,不同请求之间不能共享资源,极大的浪费了服务器资源。ISAPI技术存在开发和调试困难、稳定性差的缺点。目前被广泛使用的服务器端脚本技术(例如ASP)等,由于是解释执行的脚本语言,运行效率较低。另外,程序代码和控制浏览器显示的HTML混杂在一起,程序的可读性、可维护性差,代码复用比较困难。目前,随着网络化、信息化的快速发展,C/S结构应用逐渐向B/S结构应用转型,那些当年炙手可热的VB,PB,Delphi等RAD开发工具也在慢慢地被人们淡化,而企业及政府的信息化建设如火如荼,互联网络、信息高速公路成为新的经济腾飞点,并且一些大的企业开始从网络中获益。由于B/S结构应用开发的特殊性,基于C/S结构的RAD方法并不适应Web应用系统,人们期待新的WEB应用快速开发的方法,因此如何引入新的开发工具,统一桌面应用程序与Web应用程序开发模式的区别,分离Web应用程序的界面和代码,解决解释执行的效率问题,并且实现Web应用程序的可视化快速开发,是近年来程序开发人员广泛关注的问题。全球的许多公司也将B/S结构的开发方法列入重点研究的对象,Web应用开发的工具也成为全球许多公司开发的重要目标。目前用于网络应用开发的编程语言有两大主流类:一类是以微软的ASP为代[9]表;一类是以SUN公司的JSP为代表。微软的Studio.NET是一个比较好的可视化开发工具,但也只是在界面上拖放下控件,并没有像C/S模式下的RAD开发。以SUN公司JAVA为代表的开源团队虽有一些如Struts、Spring等的开源框架,但都没有实现真正意义上的WEBRAD开发框架,只是从意义上实现MVC的分离,开发人员仍被复杂的逻辑、频繁的跳转所困难,不能全心的投入到业务实现上面,可见在这JSP这个大本营里,基于WEBRAD开发工具不尽如人意,当前在WEB开发中迫切需要一个完全具备C/S模式优点的快速开发框架。1.1.2研究意义随着Internet和Intranet/Extranet的快速增长,Web己经对商业、工业、银行、财政、教育、政府及我们的工作和生活产生了深远的影响。许多传统的信息和数据库系统正在被移植到互联网上,电子商务迅速增长,早已超过了国界。范围广泛的、复杂的分布式应用系统正在WEB环境中出现。可以说,人类社会己经进入[10]了―WEB时代‖。如今的WEB应用程序越来越流行,WEB的流行和无所不在,2 1绪论是因为它能提供支持所有类型内容连接的信息发布,容易为最终用户存取。这也不难想象,正如Sun公司总裁Scott所说,“计算机就是网络”,随着互联网技术的发展,知识在世界范围内得到充分地传播。与此同时,WEB应用开发也取得了一定的发展,但当前无论是.NET方面提供了可拖放可视化的快速开发环境,还是在JSP方面提供了诸如STRUTS的MVC模型开发框架,从根本来看,开发人员仍然要面对WEB应用的客户服务端的无状态,复杂的请求跳转及逻辑关系多层转变,解释执行效率低下,这样将难以降低错误的出现几率;难以使开发人员专心于业务逻辑的处理上;难以提高开发的整体效率。如果有能够在WEB下实现C/S模式下RAD开发的种种优点,并且开发出一个针对WEB应用的RAD框架,这必将加快企业级应用开发的速度,从而极大的节省人力物力,并在一定程度上避免了软件开发过程存在着错误积累与放大效应。本论文就是针对WEB应用快速开发框架所做的研究。综上所述,本课题在学术和应用上都有很大的研究意义。1.2本文研究的目的和研究内容1.2.1本文研究的目的本文研究的最终结果将实现WEBRAD框架,此框架是一个以JSF框架为底层架构,采用事件响应机制,提供丰富控件库的WEB下的快速应用开发框架,其目的主要是为了提高WEB下应用程序开发的效率,提高代码的重用性,实现所见即所得的可视化拖放的控件来定制用户界面以及后台相关代码自动生成的编程环境,所有WEB页面的响应都看作一个事件处理过程来回应,使开发人员能像VB那样随心所欲的编写自己的业务逻辑,解决长期以来困扰开发人员在开发WEB应用程序下的种种局限。1.2.2本文研究的内容研究的内容先从快速应用开发入手,分析快速应用开发在C/S模式下的应用机制,以及快速应用开发所具备的条件、遵守的原则等,同时研究WEB开发与C/S模式开发的异同,建立如何在WEB应用中,也就是在B/S模式下实现如C/S模式下快速开发机制的方法。然后逐层研究控件模型原理及WEB应用响应原理进行分析,在WEB无状态下建立实现状态管理控件模型,来实现消息的封装和管理,并将所有页面信息由控件树统一管理,以此来得到相应控件的状态,并给出了如何使用JSF丰富控件库的方法。随后分析事件机制的原理,实现在WEB下控件有状态维持的情况下建立事件驱动模型,实现WEB应用的事件机制。由此,根据前面的分析研究的成果建立一个WEB下快速应用开发框架并用Eclipse的插件机制和一些开源的框架(如GEF、EMF框架)实现此框架,最后对此框架进行相应的3 重庆大学硕士学位论文测试。1.3本文的组织结构本文共分六个章节,具体内容如下:第一章,绪论,从整体上对研究的主题进行阐述,说明研究的背景、意义及国内外的现状,提出一种WEB下快速应用开发框架。第二章,WEB快速应用开发分析,主要是对快速应用开发的常用设计模式以及特点的分析,结合WEB应用程序的特征,分析实现WEB快速应用开发框架。第三章,建立WEB控件模型,分析C/S模式下控件模型,对WEB应用程序响应的底层机制分析,通过代理Servlet实现客户的请求响应状态保持,使用控件树来统一管理控件状态,使用控件生命周期,建立WEB下的控件模型。第四章,建立WEB事件机制分析,以及事件机制的特点的分析,结合上一章的控件模型,在WEB中引入事件机制驱动模型,建立WEB事件驱动机制。第五章,建立快速应用开发框架,本章主要是对快速应用开发、控件模型、事件机制以及JSF框架的用户组件扩展等多种技术的深入研究,经过需求分析、功能建模和设计开发、测试等各个环节,用JSF框架的底层机制,扩充用户控件库,重现表示层,实现控件自由拖放,代码自动生成,事件响应编程的一个所见即得的快速开发框架。并且通过开源软件Eclipse的插件机制对扩展点扩展以及GEF、EMF的扩展建立此WEB快速应用开发框架,使开发人员真正能在像VB那样的环境下实现WEB的快速应用开发。第六章,结论与展望,对本文的研究成果进行总结,分析优势与不足,以及下一步要做的工作,并对WEB下快速应用开发框架进行展望。4 2WEBRAD分析2WEBRAD分析2.1引言快速应用开发(RapidApplicationDevelopment,简写RAD),是一种比传统生命周期法快得多的最新的开发方法论,形成于80年代末与90年代初,由詹姆斯·马丁(JamesMartin)提出。顾名思义,―快速开发‖也就是实现短周期开发。与传统的软件开发方法相比,RAD是一种可将开发周期缩短2-8倍的“革命性”方法。时间、费用、品质是软件开发的三个极为重要的因素,一个优秀的开发方法在这三个方面都应该做得很好。传统的开发方法,往往在改进某一方面的同时,却影响了另一方面,而RAD则以三要素中最容易定量化的―时间‖作为最优先的考虑对象,[11]同时也可使其它各个方面有所改善。[12]RAD起源于所谓的原型工具(Prototypingtools)。利用这类工具,应用开发人员可以快速模拟出一个应用原型,从而使最终用户在真正的设计完成之前就可对该应用进行考察和试验。因此,原型化过程的最终结果就是生成的原型,这些原型简化了实际应用的其他非本质因素,只保留了应用本身的一些核心要素,一旦用户认可原型,开发人员就可以据此较快地开发出在功能上同原型基本相同的真正的应用软件。设计分析改变系统分析系统界面分析改变系统分析界面分析改变原型设计设计改变错误系统设计测试编码设计界面模型代码错误编码代码生成器测试代码代码代码测试集成产品产品a、传统开发方法b、RAD开发方法图2.1RAD与传统的比较Figure2.1CompareRADandTradition5 重庆大学硕士学位论文应该指出,原型工具仅仅只是提供了一个蓝本,对应用开发者来说,原型几乎不可能直接转化为最后的应用,原型完成之后,开发者必须使用真正的程序语言如COBOL、C等建立真正的应用。这样一来,开发者就得进行两次应用开发。为了解决这一问题,RAD工具通过给开发者提供其在建立原型并转化为最后的应用时所需的一切来对原型工具进行了扩充,从而使得RAD工具比原型工具具有明显的优势,这就是RAD工具得以产生并发展的原因。RAD工具可以说是一个很好的应用开发解决方案。与原型法不同,开发者们只需利用RAD工具进行界面设计即可,他们所做的工作只是安排按钮、菜单、数据窗口以及对话框等界面元件,他们关心的是程序做什么而不是怎么做。他们通过不断给用户演示应用、获取用[13]户反馈并不断对应用进行修改来实现应用开发。如图2.1所示。2.2RAD的常用设计模式2.2.1资源窗体资源窗体可以说是一种最简单的归类做法,就是把许多类似功能的控件,集中到一个资源窗体上面。这样不同的模块都可以共享这个资源窗体中的资源。在RAD环境中,Form是真正的容器,因此,资源窗体实际上相当于一个资源对象池和组件池,也类似于面向对象环境中的Environment类。资源窗体本身是不可见的,但是在软件运行的整个过程中始终存在。在运行期间,资源窗体也可以动态地添加和删除控件。资源窗体也可以维护一些全局的变量和状态信息等,为所有的系统和窗体所共享。使用资源窗体最重要的问题和全局变量一样,就是避免任何模块都可以更改其状态。除了主框架的程序代码之外,一切模块对于资源窗体的访问都应该是只读的。因此,类似同步信号量之类的东西不适合放在资源窗体中。2.2.2数据敏感控件开发和定制数据敏感控件显示数据,对于RAD系统的开发也是很重要的。一般的系统分层,总是倾向于进行水平划分,也就是分为展示层、逻辑层和数据层。但是在RAD开发环境中,展示层就是控件的显示,而逻辑往往直接放在和事件相应的函数中。因此在这样的开发环境中,水平分层往往不是非常明确。这时候,可以倾向进行垂直分层,就是建立数据敏感控件。控件加载数据以后,即可访问数据源来完成相应的功能。数据敏感控件直接工作在数据层上,把数据呈现出来,并且进行必要的数据处理。使用数据敏感控件可以快速地进行应用的开发和流程的变更。特别有利于系统的快速开发,可以很好地体现RAD的精髓。此外,使用数据敏感控件便于实现数据驱动,把那些对于数据统一的操作方式抽象和独立出来进行实现。6 2WEBRAD分析2.2.3MVC分层结构标准的使用把系统分为展示层、逻辑层和数据层这样独立的3层的方式来进[14]行系统的设计。每一层完成自己的职责,相互之间使用简单的调用方式关联。除了采用垂直分割的办法以外,水平分割在RAD环境中也是常见的,而3层的方式就是系统层次的水平分割,其实质就是避免界面控件直接处理应用逻辑,从而建立完整的应用逻辑层。即使对于C/S甚至3层计算架构的客户端,虽然整体系统己经是3层,但是在客户端仍然应该保持3层,特别是在拥有本地逻辑和本地数据的时候。2.2.4主框架机制主框架机制就是建立在主窗体的生存周期上的系统功能状态,也就是把整个程序的功能建立在以主窗体为代表的主框架的生存周期上面。在RAD环境中,整个程序的生存周期是在主窗体的基础上展开的。在建立RAD应用程序的时候,需要仔细地设计主框架的状态和处理的流程。通过使用相对固定的主框架,可以方便地进行应用系统功能的组合和扩展。通过换用不同的界面框架和服务模块,应用程序可以快速地满足变化的新的需求。这一点也能够体现出RAD开发快速灵活的特点。2.2.5逻辑组件化RAD开发应该追求应用逻辑的组件化,而与之相对应的是逻辑的对象化和函数化。组件机制是RAD环境的核心,复用、分发和运作的都是组件,因此,RAD典型的特征就是应用逻辑的组件化。在这样的开发环境中,系统的设计和开发被空前地紧密结合在一起。所以,设计的重点和复用的单元都是组件。RAD系统的纵向分割和横向分割都是基于模块化的,而RAD内的模块化应该尽可能地组件化而不仅仅是对象化。这一点是RAD环境和面向对象的环境的一个差别。此外,由于组件归根结底是平等的,没有层次之分。因此,其分层一般体现在组件被包含在不同层面的窗体容器中。比如资源窗体包含的组件一般就会是底层的一些东西,而交互窗体包含的就是显示层的东西,虽然这样的方式不是很严格,但是能够使得应用程序员可以直观地、可视化地看到系统的层次。2.2.6自定义事件基于控件的应用程序使事件机制关联起来,可以更好地实现系统的灵活性,这是使用RAD环境的主要特征。使用自定义的事件,可以帮助开发人员很方便地进行应用程序的扩展。RAD开发环境一般都提供了一个事件的实现机制,使得开发者只需要简单地继承和捕获事件,就可以进行事件驱动程序的开发而无需自行[15]实现复杂的事件机制。RAD开发几乎都是在使用各种控件(一种被特殊约定了交互协议的组件),从7 重庆大学硕士学位论文而可以实现可视化的操控和开发。控件之间的关联和集成是使用事件来实现的,尽量不要频繁地进行控件之间的直接调用,通过自定义事件有利于提高整个系统的扩展性。控件之间松散的耦合可以使得控件更加有效和便于重用,因此,每一个控件都应该有属性、方法、界面和响应的事件。理论上,应该把全部控件之间的交互都变成对于特殊事件的响应,组建完全松散耦合的系统。在开发应用中需要注意的一点是,虽然组件通过响应自定义的和系统的事件进行工作、沟通和协作,但是尽量不要把处理代码直接写在响应事件的函数中。很多RAD程序难于维护就是因为把业务处理代码直接写在了事件响应的方法中。按照系统设计一个原则,完成什么任务和完成任务的时机应该进行分离,在这里,我们又一次看到了分离带给我们的灵活性。业务上的工作,甚至界面上的交互逻辑都应该被封装到专门的方法中,然后在响应事件的方法中进行调用。这种分离可以使得应用逻辑和交互逻辑严格的分开,为系统的修改和维护带来方便。当然为了安全,只应用于本类和本组件的应用逻辑可以声明为―私有‖的,防止外部的调用。原则上,响应事件的方法中只包含对其他方法的调用(包括属性方法,也就是通过使用属性方法修改对象的状态)。2.3RAD工具的特点2.3.1面向对象RAD的第一个特征,就是面向对象,在RAD的产品中都采用了面向对象模式,将所有事件作为一个对象来操作,实现对象的多态、封装、继承。而这些面[16]向对象的语言都立足于现有语言。VisualBasic基于BASIC,Delphi基于Pascal,而VisualAge则基于Smalltalk。2.3.2可视化控件快速应用开发之所以能提高开发速度,在于它提供了丰富的可视化控件库,开发人员可以自由的拖放控件能快速的实现所见即所得的可视化用户界面。Borland的Delphi,IBM的VisualAge,Microsoft的VisualBasic(VB)和Symantec的EnterpriseDeveloper是这种风格的典型代表。它们都为快速构造和组装应用程序提供了高度集成的可视化控件库。2.3.3事件驱动模型[17]所谓事件驱动,简单地说就是你点什么按钮(即产生什么事件),电脑执行什么操作(即调用什么函数),当然事件不局限于用户的操作,还包括自身控件的变化响应等。构建一个包含事件驱动构架的应用程序和系统,这就使得这些应用程序和系统响应更灵敏,因为事件驱动的系统更适合应用在不可预知的和异步的环境里。这就有效的增强了应用程序的开发效率。8 2WEBRAD分析2.3.4代码的自动生成快速应用开发工具的又一大特点是代码的自动生成,当进行控件的拖放时,不用去考虑如何用代码来生成控件以及控件的相关属性,如位置、大小、颜色等[18]这些相关的代码由IDE自动生成,另外诸如对事件的编程,配置的管理等,基本的框架代码也由IDE自动生成,这大大的减少程序员的工作量,减少编程出错的机率。2.4WEB快速应用开发WEB下应用程序的开发与传统桌面应用程序的开发有一定不同,传统应用程序是基于C/S架构的,而WEB应用程序是基于B/S架构的。下面将对这两种架构进行分析。2.4.1C/S与B/S架构①什么是C/S结构。[19]C/S(Client/Server)结构,即大家熟知的客户机和服务器结构。它是软件系统体系结构,通过它可以充分利用两端硬件环境的优势,将任务合理分配到Client端和Server端来实现,降低了系统的通讯开销。目前大多数应用软件系统都是Client/Server形式的两层结构,由于现在的软件应用系统正在向分布式的Web应用发展,Web和Client/Server应用都可以进行同样的业务处理,应用不同的模块共享逻辑组件;因此,内部的和外部的用户都可以访问新的和现有的应用系统,通过现有应用系统中的逻辑可以扩展出新的应用系统。这也就是目前应用系统的发展方向。传统的C/S体系结构虽然采用的是开放模式,但这只是系统开发一级的开放性,在特定的应用中无论是Client端还是Server端都还需要特定的软件支持。由于没能提供用户真正期望的开放环境,C/S结构的软件需要针对不同的操作系统系统开发不同版本的软件,加之产品的更新换代十分快,已经很难适应百台电脑以上局域网用户同时使用。而且代价高,效率低。②什么是B/S结构。[20]B/S(Browser/Server)结构即浏览器和服务器结构。它是随着Internet技术的兴起,对C/S结构的一种变化或者改进的结构。在这种结构下,用户工作界面是通过WWW浏览器来实现,极少部分事务逻辑在前端(Browser)实现,但是主要事务逻辑在服务器端(Server)实现,形成所谓三层3-tier结构。这样就大大简化了客户端电脑载荷,减轻了系统维护与升级的成本和工作量,降低了用户的总体成本。以目前的技术看,局域网建立B/S结构的网络应用,并通过Internet/Intranet9 重庆大学硕士学位论文模式下数据库应用,相对易于把握且成本也是较低的。它是一次性到位的开发,能实现不同的人员,从不同的地点,以不同的接入方式(比如LAN,WAN,Internet/Intranet等)访问和操作共同的数据库;它能有效地保护数据平台和管理访问权限,服务器数据库也很安全。特别是在JAVA这样的跨平台语言出现之后,B/S架构管理软件更是方便、快捷、高效。②C/S和B/S之比较C/S和B/S是当今世界开发模式技术架构的两大主流技术。C/S是美国Borland公司最早研发,B/S是美国微软公司研发。目前,这两项技术已被世界各国所掌握,国内公司以C/S和B/S技术开发出产品也很多。这两种技术都有自己一定的市场份额和客户群,各家企业都说自己的管理软件架构技术功能强大、先进、方便,都能举出各自的客户群体,都有一大群文人墨客为自己摇旗呐喊,广告满天飞,可谓仁者见仁,智者见智。1)C/S架构软件的优势与劣势a.应用服务器运行数据负荷较轻。最简单的C/S体系结构的数据库应用由两部分组成,即客户应用程序和数据库服务器程序。二者可分别称为前台程序与后台程序。运行数据库服务器程序的机器,也称为应用服务器。一旦服务器程序被启动,就随时等待响应客户程序发来的请求;客户应用程序运行在用户自己的电脑上,对应于数据库服务器,可称为客户电脑,当需要对数据库中的数据进行任何操作时,客户程序就自动地寻找服务器程序,并向其发出请求,服务器程序根据预定的规则作出应答,送回结果,应用服务器运行数据负荷较轻。b.数据的储存管理功能较为透明。在数据库应用中,数据的储存管理功能,是由服务器程序和客户应用程序分别独立进行的,前台应用可以违反的规则,并且通常把那些不同的(不管是已知还是未知的)运行数据,在服务器程序中不集中实现,例如访问者的权限,编号可以重复、必须有客户才能建立定单这样的规则。所有这些,对于工作在前台程序上的最终用户,是―透明‖的,他们无须过问(通常也无法干涉)背后的过程,就可以完成自己的一切工作。在客户服务器架构的应用中,前台程序不是非常―瘦小‖,麻烦的事情都交给了服务器和网络。在C/S体系下,数据库不能真正成为公共、专业化的仓库,它受到独立的专门管理。c.C/S架构的劣势是高昂的维护成本且投资大。首先,采用C/S架构,要选择适当的数据库平台来实现数据库数据的真正―统一‖,使分布于两地的数据同步完全交由数据库系统去管理,但逻辑上两地的操作者要直接访问同一个数据库才能有效实现,有这样一些问题,如果需要建立―实时‖10 2WEBRAD分析的数据同步,就必须在两地间建立实时的通讯连接,保持两地的数据库服务器在线运行,网络管理工作人员既要对服务器维护管理,又要对客户端维护和管理,这需要高昂的投资和复杂的技术支持,维护成本很高,维护任务量大。其次,传统的C/S结构的软件需要针对不同的操作系统系统开发不同版本的软件,由于产品的更新换代十分快,代价高和低效率已经不适应工作需要。在JAVA这样的跨平台语言出现之后,B/S架构更是猛烈冲击C/S,并对其形成威胁和挑战。2)B/S架构软件的优势与劣势a.维护和升级方式简单。目前,软件系统的改进和升级越来越频繁,B/S架构的产品明显体现着更为方便的特性。对一个稍微大一点单位来说,系统管理人员如果需要在几百甚至上千部电脑之间来回奔跑,效率和工作量是可想而知的,但B/S架构的软件只需要管理服务器就行了,所有的客户端只是浏览器,根本不需要做任何的维护。无论用户的规模有多大,有多少分支机构都不会增加任何维护升级的工作量,所有的操作只需要针对服务器进行;如果是异地,只需要把服务器连接专网即可,实现远程维护、升级和共享。所以客户机越来越―瘦‖,而服务器越来越―胖‖是将来信息化发展的主流方向。今后,软件升级和维护会越来越容易,而使用起来会越来越简单,这对用户人力、物力、时间、费用的节省是显而易见的,惊人的。因此,维护和升级革命的方式是―瘦‖客户机,―胖‖服务器。b.成本降低,选择更多。大家都知道windows在桌面电脑上几乎一统天下,浏览器成为了标准配置,但在服务器操作系统上windows并不是处于绝对的统治地位。现在的趋势是凡使用B/S架构的应用管理软件,只需安装在Linux服务器上即可,而且安全性高。所以服务器操作系统的选择是很多的,不管选用哪种操作系统都可以让大部分人使用windows作为桌面操作系统电脑不受影响,这就使得最流行免费的Linux操作系统快速发展起来,Linux除了操作系统是免费的以外,连数据库也是免费的,这种选择非常盛行。比如说很多人每天上―网易‖网,只要安装了浏览器就可以了,并不需要了解―网易‖的服务器用的是什么操作系统,而事实上大部分网站确实没有使用windows操作系统,但用户的电脑本身安装的大部分是windows操作系统。c.应用服务器运行数据负荷较重。由于B/S架构软件只安装在服务器端(Server)上,网络管理人员只需要管理服务器就行了,用户界面主要事务逻辑在服务器(Server)端完全通过WWW浏览器实现,极少部分事务逻辑在前端(Browser)实现,所有的客户端只有浏览器,网络管理人员只需要做硬件维护。但是,应用服务器运行数据负荷较重,一旦发11 重庆大学硕士学位论文生服务器―崩溃‖等问题,后果不堪设想。因此,许多单位都备有数据库存储服务器,以防万一。3)C/S与B/S区别Client/Server是建立在局域网的基础上的,Browser/Server是建立在广域网的基础上的。a.硬件环境不同C/S一般建立在专用的网络上,小范围里的网络环境,局域网之间再通过专门服务器提供连接和数据交换服务。B/S建立在广域网之上的,不必是专门的网络硬件环境,例如电话上网,租用设备,信息自己管理,有比C/S更强的适应范围,一般只要有操作系统和浏览器就行。b.对安全要求不同C/S一般面向相对固定的用户群,对信息安全的控制能力很强。一般高度机密的信息系统采用C/S结构适宜,可以通过B/S发布部分可公开信息。B/S建立在广域网之上,对安全的控制能力相对弱,面向是不可知的用户群。c.对程序架构不同C/S程序可以更加注重流程,可以对权限多层次校验,对系统运行速度可以较少考虑。B/S对安全以及访问速度的多重的考虑,建立在需要更加优化的基础之上。比C/S有更高的要求,B/S结构的程序架构是发展的趋势,从MS的.Net系列的BizTalk2000Exchange2000等,全面支持网络的构件搭建的系统。SUN和IBM推的JavaBean构件技术等,使B/S更加成熟。d.软件重用不同C/S程序可以不可避免的整体性考虑,构件的重用性不如在B/S要求下的构件的重用性好。B/S对的多重结构,要求构件相对独立的功能。能够相对较好的重用。就如买来的餐桌可以再利用,而不是做在墙上的石头桌子。e.系统维护不同系统维护是软件生存周期中,开销大,相当重要的一部分。C/S程序由于整体性,必须整体考察,处理出现的问题以及系统升级难,可能是再做一个全新的系统。B/S构件组成方面构件个别的更换,实现系统的无缝升级。系统维护开销减到最小,用户从网上自己下载安装就可以实现升级。f.处理问题不同12 2WEBRAD分析C/S程序可以处理用户面固定,并且在相同区域,安全要求高的需求,与操作系统相关,应该都是相同的系统。B/S建立在广域网上,面向不同的用户群,分散地域,这是C/S无法做到的,与操作系统平台关系最小。g.用户接口不同C/S多是建立在Window平台上,表现方法有限,对程序员普遍要求较高。B/S建立在浏览器上,有更加丰富和生动的表现方式与用户交流,并且大部分难度减低,降低开发成本。h.信息流不同C/S程序一般是典型的中央集权的机械式处理,交互性相对低。B/S信息流向可变化,B-B、B-C、B-G等信息流向的变化,更象交易中心2.4.2WEBRAD分析在WEB开发中,由于它本身的独特性实现快速应用开发还存在一定的问题。在WEB应用中,目前来说动态构建页面分为两个大的派别,一个是以微软为代表的ASP,一个是以SUN公司为代表的JSP。ASP使用的编程语言是VBScript之类的脚本语言,JSP则是JAVA,这是两者之间最明显的区别。两种语言引擎用完全不同的方式处理页面中嵌入的程序代码。在ASP下,VBScript代码被ASP引擎解释并执行;在JSP下,代码被编译成Servlet并由Java虚拟机执行。这种编译操作只在对JSP页面的第一次请求时发生,后期请求将直接调用编译好的文件。由于Java语言的开源性和跨平台性,以及JSP很好地实现了多层结构,特别是得了J2EE的支持,因此得了迅速发展,本文的快速应用开发主要是基于JAVA语言相关的。通过前面对传统模式下的RAD的分析可以知道,要在B/S架构下实现RAD,同样也要具备C/S模式下RAD的特点与功能。框架的概念在WEB应用开发中早已引入,特别各种开源框架将框架的应用更进一步的推广,如STRUS、SPRING等框架,也就是说在WEB应用开发中实现主框架是没太大的困难;再者是对框架内的资源进行管理、监控,这些是任何一个框架应当能实现的最基本的功能;对于统一数据服务、界面层与逻辑层分离同样与WEB应用开发MVC模式的发展相吻合,MVC模式是一种将视图,视图控制,逻辑控制分离的经典开发模式。它成功应用于大量的C/S开发中,大大清晰了开发人员的思路,提高了开发效率。近年来引入到B/S模式下,在这上面已取得了丰富的经验和知识积累,因此RAD的这一设计模式也可以在WEB应用实现。要在WEB下实现RAD最主要的是三个方面:一个是控件模型,一个是事件驱动模型,再一是数据持久化。13 重庆大学硕士学位论文在WEB应用中实现控件模型,可以提高软件的重用率,而WEB应用程序展示在用户面前的是由一些具体的诸如按钮、单选框等组成的页面,只要对些视图进行合理的化分,可以将页面全由控件来构成,而HTML语言也在这方面有了一定粒度的化分,如表单由标签

表示,下拉框由标签表示,因此可将这角色单一,关联比较大作为一个控件。以此在WEB中实现控件模型是可行的。目前已有一些框架实现了部分的控件模型。在RAD中,模块内应当将其控件化,为使提高开发效率应当提供足够丰富的常用的控件,这个我们会在下面章节分析如何实现。事件驱动模型在C/S中是一个比较容易实现的过程,用户每做出的一个动作,都将由事件监听来获取此事件,然后驱动对应的事件做出回应,从而完成用户操作需求。控件模型主要是为事件驱动细粒度的变化提供基础。为实现对控件状态变化的监控,必须清楚知道控件在请求前和响应后的状态。在WEB应用中,整个过程由WEB客户端(即WEB浏览器)和WEB服务器组成,它们之间是通过因特网进行会话的,而这种会话是通过一种叫做HTTP的标准网络传输协议完成的,而HTTP传输协议是―无状态‖协议,服务器对于每一次来自浏览器的请求都当作完全新的用户,服务器并不知道之前用户对页面做了一些什么动作,也就是无记忆的,因此,要在B/S模式下实现控件模型还是有一定的困难,首先要知道用户动作前后的页面的状态,然后将这些状态统一管理起来。为实现页面状态的管理,如常用的Session的管理,可以将请求响应的动作统一由某一类统一管理,然后再根据需求做出相应动作,如使用AgentServlet来作总代理,此类主要是对页面内控件的状态进行管理,生成一个对象实例,此实例放置此次请求前所有控件的状态,包括有多少个控件,控件之间是什么关系以及控件的位置、大小、颜色等属性,等到请求发来时,根据需要对控件做出变更,如改变控件数量,控件位置等,之后将控件的状态放入对象实例,完成响应过程。这样就实现了消息的―有状态‖,正如将这些消息放入一个容器,来监听这些状态的变化。有了前后状态的变化信息事件驱动的可能性就可以实现,也就是当对控件的状态有了监控时,可以对控件相应的变化进行事件响应,如用户点击按钮或用户在文本框内改变了数据内容,均可对此变化进行事件编程,根据控件的前后状态来对控件进行控制,完成请求的响应。数据的持久化是将使用内存中的数据保存到磁盘的操作,同时也包括数据的存储、访问和管理。在传统的模式中,企业级应用系统的开发中都是在业务逻辑层中利用大量的SQL硬编码语句来实现对数据库中数据的存取,业务逻辑中混有数据存取逻辑,代码可维护性和可扩展性差。所以采用增加数据持久层的方法来隔离业务逻辑层和数据库,用于从数据库中存取对象,数据持久层中定义了存取14 2WEBRAD分析对象的接口,业务逻辑开发人员通过这个接口来访问数据库。在这个层中集中了数据库访问的代码,当更换数据库产品时不会影响到上层代码,这样的结构清晰明快。所以说持久层的实现主要是把实体类映射到数据库表,并对实体类对象进行查询、添加、修改、删除等具体操作。目前JDO、Hibernate等框架在数据持久化层做的比较成熟,均实现了ORM(Object-RelationalMapping)即对象-关系映射,实现实体域对象的持久化并封装数据访问的细节,对本文只需要研究如何将这些框架整合到RAD框架中来。15 重庆大学硕士学位论文16 3建立WEB控件模型3建立WEB控件模型3.1控件模型控件在RAD中的应用非常广泛,也之所以有这些丰富的控件才使得快速开发[21]成为可能。控件(Contrl)就是具有用户界面的组件(Component),而组件是指一段经常用到的公共代码,封装在某个单元模块中。控件可以直接通过界面与用户进行交互。如果一个组件具有用户接口或界面,就称之为控件。控件是组件的一个主要样本(并且历史上曾驱动着组件的开发),控件又不仅仅是唯一的一种组件。组件不需要显示任何信息或用户界面。组件可能实现科学计算,收集性能数据,如计算1971年1月1日到现在的毫秒数,抑或是读取布什总统竞选活动保险箱里的美金数。控件的开发方法以面向对象方法为基础,它是界面、属性、方法、事件的一[22]个封装。它实现了部分功能,能够被很好地调用。同时用户通过继承和修改系统控件库所提供的控件,使其拥有新的属性、方法和事件处理,就可以得到自定义控件。RAD工具提供了大量的控件,用于设计用户的界面,程序员可以通过拖放的操作来完成界面的设计工作,这样做不仅减轻了工作量、简化了界面设计过程,而且有效地提高了开发效率及可靠性。3.1.1控件的三大要素①方法控件的方法是该控件可能被要求去执行的动作。不同控件具有不同的方法,例如,在窗体和图片框等控件中,具有Pset、Line、Cls等绘图方法,而对于滚动条、列表框等则不具有绘图方法。如图3.1所示。方法控件属性事件图3.1控件三要素Figure3.1ThreeKeyelementsofControl②事件17 重庆大学硕士学位论文控件的事件是控件对某些动作的响应,事件的触发常用于对自身控件或其它控件的变更过程。例如,在一个控件上单击或双击鼠标,都会引起控件的相应事件作为响应,或者改变本身的状态,或者去操作其它控件的生成、销毁等。③属性控件的属性提供了对控件的描述,这通常是静态的对控件的描述。如对控件的大小、背景色、位置等描述。3.1.2控件生命周期一般来说控件有两种状态,一种是运行态,一种是非运行态。运行态是在程序执行过程中的状态,每个控件在运行时都有一个生命周期,从控件的生成、控件的执行以及到控件的销毁,在这个过程中所有控件的状态由统一的对象来管理维护,什么时候生成控件,什么时候控件执行动作等,这些功能的管理不需要开发人员专门来写代码来维护,而是由RAD开发工具本身来完成,也就是每个应用程序编写的时候底层机制已经实现了对控件的管理。传统下的控件一般是由一个Form来统一管理,记录控件在执行时的状态,如控件的数量、位置、大小等一些相关的属性和方法,并且在事件触发时来通知控件所做的动作。对控件的管理是非常重要的,程序的界面主要是由控件组成,由一个专门的管理对象来管理也符合认识规律,在C/S模式下控件的管理是比较容易实现的,在客户端控件的状态是持久的,只需要对当前的控件进行遍历,记录各个控件的状态。当一个事件被触发时,根据事件的请求判断请求所要执行的动作,对应的去操作界面上的控件,需要生成新的控件就调用控件生成,需要销毁控件时就调用控件的销毁或其它的动作,然后再对界面的控件重新重组,同时记录下各个控件的状态,并监听控件的事件,为下次变化做出准备,这就是控件在运行时的整个过程。如图3.2所示。响应完成控控事更件件件新遍视响控历图应件图3.2控件生命周期Figure3.2LifecycleofControl非运行态是指控件在开发阶段的状态,此状态主要是控件在界面中的所见所得的过程以及控件的布局,当保存设计的界面时要保存各个控件的相关内容,如18 3建立WEB控件模型名称、位置、大小、标识等,以便在下次打开此界面的能重现控件的布局及相当信息。3.2建立WEB控件模型建立WEB控件模型首先要清楚WEB应用程序开发的机制,然后根据WEB开发的特点来设计WEB控件模型,WEB控件模型最大的难度是对控件状态的管理。3.2.1HTTP请求—响应模型[23]HTTP即HypertextTransferProtocol,是Web应用中浏览器与服务器之间用于传送超文本文件的标准协议。从网络协议的角度,HTTP协议是对TCP/IP协议集的扩展,处于TCP/IP层次的应用层。HTTP是基于客户机/服务器模式,且面向连接的。典型的HTTP事务处理有如下的过程:①客户与服务器建立连接;②客户向服务器提出请求;③服务器接受请求,并根据请求返回相应的文件作为应答;④客户与服务器关闭连接。客户与服务器之间的HTTP连接是一种一次性连接,它限制每次连接只处理一个请求,当服务器返回本次请求的应答后便立即关闭连接,下次请求再重新建立连接。这种一次性连接主要考虑到WWW服务器面向的是Internet中成千上万个用户,且只能提供有限个连接,故服务器不会让一个连接处于等待状态,及时地释放连接可以大大提高服务器的执行效率。如图3.3所示HTTP是一种无状态协议,即服务器不保留与客户交易时的任何状态。这就大大减轻了服务器记忆负担,从而保持较快的响应速度。HTTP是一种面向对象的协议。允许传送任意类型的数据对象。它通过数据类型和长度来标识所传送的数据内容和大小,并允许对数据进行压缩传送。当用户在一个HTML文档中定义了一个超文本链后,浏览器将通过TCP/IP协议与指定的服务器建立连接。从技术上讲是客户在一个特定的TCP端口(端口号一般为80)上打开一个套接字。如果服务器一直在这个周知的端口下监听连接,则该连接便会建立起来。然后客户通过该连接发送一个包含请求方法的请求块。HTTP规范定义了7种请求方法,每种请求方法规定了客户和服务器之间不同的信息交换方式,常用的请求方法是GET和POST。服务器将根据客户请求完成相应操作,并以应答块形式返回给客户,最后关闭连接;从具体用户来讲客户端是使用浏览器,向网络上的一个服务器发出HTTP请求。这个请求与服务器的位置信息一起由统一资源定位符(UniversalResourceLocation,URL)来标志,服务器分析达到19 重庆大学硕士学位论文的信息,然后向用户端浏览器返回一个响应,这个响应可以是普通的HTML文件,多媒体的图片、声音或视频文件,也可以是JavaApplets等任何可以被客户端识别并显示的内容。一些特殊的URL地址会使服务器调用特殊的服务器端程序,使服务器生成动态的响应,一般是生成HTML文件。这是所有Web应用程序工作的基本原理。建立连接发出请求信息发出响应信息关闭连接客户机服务器图3.3Http请求-响应模式Figure3.3HttpRequest-Responsemodel3.2.2WEB开发模型在网络发展初期,在Web上发布的页面都是静态页面,不需要动态生成页面,用户也还没有提出访问数据库的要求。那时的Web应用程序是建立在两层的网络逻辑模型之上的。即网络的层次中只有客户端浏览器和Web服务器,如图3.4所示。FirstLayer客户端SecondLayer服务器图3.4两层开发模型Figure3.4Twotiersdevelopmentmodel此时的浏览器通过URL定位己知的地址发送请求,该Web服务器接收客户端的请求,将客户端所要求的页面作为响应页面,直接传递给客户端浏览器,即完成了响应过程。20 3建立WEB控件模型目前的Web应用大多都是基于用户的需要产生动态页面,服务器端多有数据库的存在,在响应过程中常常需要操作数据库。Web开发的逻辑结构以多层为主。这时的应用程序被划分为可在不同的软硬件平台上多计算机上运行的多重组件。应用程序组件被赋予给不同的逻辑层。逻辑层的划分是按照不同部分所行使的功能来划分的,每个相对独立的功能被划分为一个逻辑层。逻辑层和物理层不一定具有直接的一一对应关系。例如,在不同的逻辑层行使功能的应用程序可能都运行在同一个物理层以内。除了Web服务器。许多应用系统还使用了应用服务器。用户通过浏览器访问Web服务器,然后Web服务器触发应用服务器,使之来处理客户端请求,并把应用服务器的处理结果返回给浏览器。图3.5表示了目前Web应用系统的逻辑层的划分,采用多层结构的请求—响应模型。BrowseApplicationClientWebServerWebServerBusinessBusinessObject/componeObject/componeApplicationDatabaseDataServer图3.5多层开发模型Figure3.5Multi-tiersdevelopmentmodel第一层是客户端Web浏览器。浏览器与Web服务器通过HTTP协议进行通信。浏览器通过HTTP协议向Web服务器发送文档请求,Web服务器将HTML或者XML文本返回给客户端浏览器。第二层是Web服务器。Web服务器接受用户的请求并进行分析。如果用户是请求的是静态的HTML文本则服务器将直接HTML文件返回给浏览器。如果用户请求的是动态的信息则根据需要进行处理,或者将请求交给applicationserver进行处理,之后将处理结果以HTML,XML文件形式返回给用户。第三层位于Web服务器和企业数据资源层之间,负责处理应用系统的事务逻辑。具体执行数据处理、业务逻辑的对象和组件等处在本层。该层的存在防止了21 重庆大学硕士学位论文客户层对数据存储层的直接访问,大大地增强了整个系统的安全性。本层是Web开发模型的核心层,传统的Web应用程序使用以通用网关接口(CGI)为基础的开发技术,但是以新的Web应用程序开发技术如ASP.NET等更加高效、快捷,正在越来越多的为人们所使用。第四层,或者称为数据层包含应用系统的数据资源。在Web应用系统中本层包括数据库和事物处理监控器,负责数据的存储并对存取过程进行管理,对它的[24]存取是由第三层来控制的。层与层的区分完全是出于逻辑上的需要,它们之间并不是有着极为严格的区分界限,这几层既可以分别运行于几台不同的机器上,也可以运行于两台或同一台机器上。分层的目的是使系统的结构更清晰,在进行软件的开发时的逻辑更清楚,分工更明确。3.2.3WEB控件模型由上面介绍可知,在B/S模式下建立WEB控件模型必须对控件的状态进行维护,也就是服务器常用一种―状态管理‖,如Session的管理。因为每一请求和响应都是无状态的,也就是说执行一次操作程序对这些控件是无记忆的,为了维护住控件的状态,须对上一次的控件状态进行保持,待下一次请求出现,可以根据相应的动作对上一次的控件变更。为此可在服务器端设立总代理(如使用AgentServlet代理),此代理将所有的请求和响应代理,然后转交控制权给控件生命周期,同时生一个控制的管理控件的实例,控件生命周期开始对控件进行管理,进入控件生命周期和其它信息进行监控,这也是WEB中常用的一种模式。如图3.6所示:响应BrowserAgentServlet请求生成实例转交后台处理控制管理控件权例实理管控件生命周期图3.6WEB控件模型Figure3.6WEBControlModel在此模型下,控件的状态可以维持住,也就是一旦启动WEB应用程序,服务器端就生成一个管理控件的对象,将此次控件的状态及相关信息放入管理控件的对象中,根据需要对控件进行操作,下一次请求来之前,控件的状态是可见的,不是无状态的,这就可以根据请求的内容对控件进行变更,也就控制了控件的产生、运行、销毁的过程,管理了控件的生命周期。由于WEB应用的特殊性,展现在客户面前的是以HTML语言为载体的页面,22 3建立WEB控件模型而其它动态的网页最终也是以HTML为载体,而HTML语言是一种很有层次的语言,因此相应的控件(如按钮、单选框等)也有很强的层次性,因此可以对所有的控件进行层次性管理,层次性管理使用树结构最为便捷。为此可在管理控件的对象中生成一个控件树,每一次请求响应,先对页面内的控件进行遍历,根据控件的相互关系生成控件树,有嵌套的控件则有子树,然后检查每个控件,是否有事件请求,然后执行相应的事件,最后更新这些控件,将请求后的响应发回客户端,这个过程统一由控件生命周期对控件树进行管理。通过重建这棵控件树来开始控件生命周期的处理过程,使用URI的路径信息部分对控件树标识,此标识符在整个应用范围里是唯一的。控件树中的控件通常由两种基本类型的控件组成:容器控件和基本控件。容器控件可以在其内部嵌套任意数目的控件,而基本控件则不行。使用这两种简单的控件类型,开发者可以建立更大控件,而后者又能被组合到更大、更复杂的控件中。这种控件层次结构允许创建多姿多彩的用户界面[25]成为可能。使用整体-部分的控件层次可使用Composite模式实现,该模式通过一个公共接口,允许对这些控件类型一视同仁,意在组成任意复杂度的整体-部分控件层次结构,同时将单个控件或复合控件视为统一的接口。可以建一个抽象控件类AbstractControl,此类有add、remove、getChild等方法,单个和复合控件继承它。如图3.7所示。图3.7Composite模式的结构Figure3.7StructureofCompositeModel在此模式下,可以实现控件的嵌套,抽象类定义的所有控件的公共接口,它还实现了这个公共接口,以提供默认的行为,其中部分行为用来访问和管理嵌套控件等。23 重庆大学硕士学位论文24 4建立WEB事件驱动模型4建立WEB事件驱动模型4.1事件机制事件驱动体系架构(Event-DrivenArchitecture,EDA)是一种设计和构建应用的方法,其中事件触发消息在独立的非耦合的模块之间(它们之间不需要知道对方)[26]传递。事件源通常发送消息到中间件或消息代理,订阅者订阅这个消息。因为事件消息使用发布/订阅方式通过消息代理传输,一个事件可以传送给多个需要者。EDA和Web服务体系架构之间的主要区别是:在Web服务体系架构中发布者和需要者只有一对一的关系,而EDA中,事件发布者最终可以传送消息给基于订阅规则在MessageBroker注册的任何数量的消费者。事件驱动的模型如图4.1所示,事件调度程序作为输入设备和应用程序之间的中间媒介。事件调度程序是服务器,而应用程序是客户。事件调度程序将输入设备的输入作为事件,并把它们作入事件消息。一般地,一个应用在一段时间内是活动的,事件调度程序清楚这是哪个应用并能根据事件流去引导它。与鼠标相应用程序A关息事消件件事鼠标事件调度程序应用程序B件关事盘相键盘与键应用程序C图4.1事件驱动模型Figure4.1Event-DrivenModel通用的事件驱动系统如图4.2所示,包括产生未加工事件的事件发生器、服务器或者对事件消息中的未加工事件进行处理和编码的事件调度程序及接收事件的客户端。客户端仅为在特定应用中使用的事件提供执行代码(也叫消息处理程序)。客户为事件0和1提供执行代码,而事件2没有被使用。即事件驱动可能发送了三种类型的事件消息,但客户将执行只感兴趣的事件0和1。另外,客户是一种消极模型,它从事件调度程序接受事件消息,标识事件类型并且将其返回到适当的执行代码中。这使得客户在所有被送的事件消息中处于非智能过程。25 重庆大学硕士学位论文发送事件发生器服务器未加工事件客户端A服务将事件转换成事件序列事件序列event_0event1excute_event_0();event0event_1event1excute_event_1();event1event_2event1do_nothing();event2图4.2通用事件驱动系统Figure4.2UniversalEvent-DrivenSystem4.1.1事件驱动概念模型事件驱动机制是指应用程序按照事件发生的次序随机执行而不是按照编程时就定义好的顺序执行,当某个事件发生时,程序将找到相应的事件处理程序来处[27]理事件。构建一个包含事件驱动构架的应用程序和系统,这就使得这些应用程序和系统响应更灵敏,因为事件驱动的系统更适合应用在不可预知的和异步的环境里。事件驱动系统的基本观点是一个系统对外部的表现可以从它对事件的处理表征出来,概念上的事件驱动系统如图4.3所示。输入输出事件接收器事件处理反馈图4.3事件驱动概念模型Figure4.3Event-DrivenConceptModel实际操作中,为简化事件驱动模式系统的设计、实现和使用,需定义一个接口(或抽象类),让它既代表执行系统,又代表执行系统的容器(管理系统)。在事件驱动模式系统中,定义这个接口的名字为EventSystem,已声明了一些与事件驱动相关的操作,例如EventProcess(事件处理器)。同时也声明了所有的管理系统共享的一些操作,例如EventDistribute(事件分发器)和EventCollect(事件收集器)。其结构用UML类图描述如图4.4所示。26 4建立WEB事件驱动模型图4.4事件驱动类图Figure4.4ClassofEvent-Driven在分布式系统中,事件是异步非耦合的,这是系统实时性的要求。因为在分布式系统中,往往各个关键应用既是服务器应用,也是客户端应用,相互之间从功能上看是对等关系,如果在同步情况下,一个应用驱动了另一个应用的事件,这个应用则必须堵塞,以等待事件执行的返回状态,这样这个应用在这段时间内则不能处理实时事件。而各个应用之间相互不完全依赖的情况也决定了分布式系统中事件的两端必须为非耦合的。事件驱动的开发模型包括如下几个部分:①事件定义库该库定义了应用所有认知的事件描述,基本信息包括事件标识,事件特征,事件处理例程,事件所属软件包等。②事件检测模块该模块负责处理事件的收集和分发,当接收事件后,分析事件的类型、特征,然后做出相应的处理,该模块是开发模型的核心。③事件执行模块该模块负责获知事件入口,解码事件携带数据,正确执行相应事件。事件执行模块可以支持事件的持久性,持久性事件的接收方如果中间停止,而在再次启动后仍可以接收事件。④事件信道事件信道是分布式应用之间事件流动的通道。事件信道是单向的,适应分布式应用的多样性要求,事件信道存在多种类型,主要有:27 重庆大学硕士学位论文1)永久可靠的信道。应用之间具有频繁的事件往来或固定的周期性的关键事件要采用这类信道。2)一次性可靠信道。事件的收发具有偶然性,非经常性,但是事件不可丢失。3)广播数据报不可靠信道。信道上的事件是一对多的关系,可以容忍偶然的数据报丢失或失序,如某一些关键应用的指示存在的事件可采用该类信道。4)单播数据报信道5)数据报可靠信道。这类信道主要适应于一对多的可靠事件,该信道在不可靠数据报基础上增加了数据报序列号和事件重发请求,以便形成可靠的事件通道。事件通道为分布式应用提高运行效率提供了基础设施。⑤事件输入源事件输入源是驱动事件的源应用。包括了事件数据的编码和封装,编码是为了使得事件可以在不同的系统平台上流动,封装的事件数据中,头部信息固定的为公共可以识别的信息。⑥提供事件驱动应用APIAPI包括了事件的注册API,以及实现以上各功能的各类API.。事件的注册过程实际上是定义事件信息,将信息写入事件定义库的过程。API要求简单明了,为快速构建分布式应用提供支持。4.1.2事件驱动的开发模型①事件驱动模型的组成[28]事件驱动模型的组成如图4.5所示。Subscriber(register)PublisherSubscriber(DataSource)(EventSink)FireEvent创建t)(epcccreaate()收接EventData图4.5事件驱动模型组成Figure4.5MakeupofEvent-DrivenModel28 4建立WEB事件驱动模型Subscriber需事先和Publisher预订要接受其发布的某事件,如图4.6中的al;Publisher在某事件发生以后,必须先生成该事件的相关数据对象,a2.1:然后通过方法调用来通知Subscriber,a2.2:也就是以回调(callback)的方式来通知Subscriber。当然在预订时,并不一定要由Subscriber自身来预订,也可以由另一个对象来帮忙预订。其动态图如图4.6所示。a1register(s):Publishers:Subscribera2.2eventhappened(data)a2.1newdata:EventData图4.6事件驱动动态图Figure4.6DynamicofEvent-Driven②事件一个事件应该包括两个属性:识别事件的名称(eventidentity,和事件的相关的数据(eventdata)。在Java的编码模式当中,回调可以使用接口模式,也就是publisher必需事先定义好一个在发布事件中使用的接口,subscriber实现该接口中的方法,publisher则通过调用接口中的方法来完成发布事件的式作。如图4.7所示。事件源事件监听者(EventSource)发布事件(EventListener)(fireevent)事件监听接口(EventListenerInterface)图4.7事件驱动回调接口模式Figure4.7InvokeinterfaceofEvent-Driven在Java的编码模式中,一个事件的识别名称就是接口名称和其中的方法名称,而事件数据则为接口方法的参数。例如:publicinterfaceKeyListenerextendsEventListener{publicvoidkeyTyped(KeyEvente);publicvoidkeyPressed(KeyEvente);29 重庆大学硕士学位论文publicvoidkeyReleased(KeyEvente);}由于一个接口中可以包含多个方法,所以Java在设计事件的时候,是将一组相关联的事件放在一起,这样设计的优点是可以很好的将事件做分类,并且在publisher中如果要处理的事件较多的话,可以使用比较少的成员变量来记录subscribers。③事件的预订和发布Publisher必需能够接受多个subscribers的预订,所以在publisher当中必需维护预订者的列表以供将来发布事件使用。在Java语言的模式中,并没有提供特别的东西来帮助这件事,可以自己用collection类来做,例如可以使用ArrayList对象来做记录。Java的预订方法名的风格为addXXXListener(),因为在publisher端必需把subscriber对象―添加‖到预订者列表后面。对于subscriber来说,预订动作的内部处理是黑箱的,subscriber不用关心publisher是如何做预订记录的。参考如下代码段:classPublisher{privateArrayListlistenerList=newArrayList();publicvoidaddKeyListener(KeyListenerI){listenerList.add(I);}publicvoidfireKeyPressedEvent(intkeyCode){Iteratoriter=IistenerList.iterator();while(iter.hasNext()){KeyListenerI=(KeyListener)iter.next();I.keyPressed(keyCode);}}}④事件数据事件发布中被传递的―事件数据‖是事件模型中的重要角色。一个subscriber在接受同一种事件的时候,可能来自不同的publisher,所以希望知道发出事件的人是谁,也就是在传递的参数当中,必需包含一个publisher对象的引用。在Java中,推荐所有的事件数据类都继承java.util.EventObject类。因为在生成一个EventObject对象的时候,必须给一个eventsource对象作为参数。然后可以通过EventObject的getSource()方法来取得这个对象。在EventObject里面,并没有包含其他任何事30 4建立WEB事件驱动模型件数据,所以如果在事件的传递过程当中,任何事件数据需要传递,就必须从EventObject派生出一个新的子类出来。如图4.8所示。KeyEventHandlerDelegate增加/移除(add/remove)事件发布者事件监听者(EventPublisher)发布事件(fireevent)(EventListener)图4.8事件数据Figure4.8EventData4.2建立WEB事件驱动模型4.2.1WEB状态管理在以前的JAVAWEB应用的开发模式中,一般采用的是Request-Response处理机制,即:客户端发送个一个HTTP请求到服务器,服务器收到请求后通过响应方式把结果返回给客户端,用户可以查看返回的结果;如果结果有多页,用户查着别的页面时又发送个请求到服务器端,如此反复地完成客户端与服务器端的交互。由于HTTP传输协议是―无状态‖协议,服务器对于每一次来自浏览器的请求都当作完全新的用户,为了保持状态信息,许多应用服务器都提供―状态管理‖,就是通常所说的Session管理。这样就给最终用户一个无缝集成的假象,好像每次自己的请求都被服务器识别为来自一个特定用户的请求。另外加上HTML本身的特点,利用这些机制来进行事件驱动开发显然是有困难的。这种基于Request-Response处理机制的开发方式和传统RAD开发即桌面应用程序开发方式不同,在桌面应用程序开发中的两个关键技术:控件技术和事件驱动机制,这两个技术是相互关联的,控件只有实现了事件机制,才使得控件更为灵活;而事件机制也只有将控件作为载体,事件才能进行细粒度的化分。将两者结合起来使用才使得开发人员可以通过控件的拖拽、设置属性和编写事件脚本进行快速开发,然而这两个技术是WEB应用开发中长期以来所缺乏的。WEB事件处理和传统C/S下应用程序的事件处理采用不同的方式,在C/S模式下,一切控件的状态信息在程序运行阶段都一直保存在内存中,而B/S模式下的客户端与服务器并不是总是处于连接状态,仅在必要的时候才进行连接通讯。所以为实现对控件状态的保存可以将控件的状态信息保存在服务器或客户端上,在下次的请求中依据这些信息重新构造出控件树和恢复控件状态;另外当客户端表单中有值改变的时候,服务器应该直到包含有该新值的请求发送给它的时候才能―感觉‖到这些变化。如单击一个按钮或一个链接的时候,将产生ActionEvent事31 重庆大学硕士学位论文件,也就产生一次新的请求,可以把这种事件分成两种:仅影响用户界面的事件(比如更新页面控件数)和将调用后端处理逻辑的事件(如更新数据库),对于仅影响用户界面的事件,应该避免对后端处理逻辑代码的调用,对于调用后端处理逻辑的事件,应该等所有请求参数都准备好,才进行触发处理。为了解决以上这此问题,可采用定义请求处理生命周期的方法,请求处理生命周期由系列阶段组成。事件的请求响应转换为控件的请求响应,请求处理生命周期应当包括控件的生命周期,在期间可以对事件的请求进行操作,根据响应的动作去更改控件的生命周期状态,产生或者销毁,也可能是位置、大小发生变化。由此,请求处理生命周期对控件生命周期及相关信息的对象化实现了―状态管理‖,有这些信息的状态就可以在WEB下实现事件机制,事件响应产生的效果可以对当前页面上的控件进行操作,可见―状态管理‖在事件驱动模型上是非常重要的。在上一章已实现了在WEB下控件模型,本章主要是对如何在WEB下实现事件模型。4.2.2WEB事件模型WEB事件也是MVC架构中一个重要方面,本文中RAD框架就是基于MVC[29]架构的,而在MVC中常用处理事件的是Observer模式,该模式是将对象内部状态的改变自动通知给对此感兴趣的相关对象。对用户界面来说,该模式为MVC模式中Model、View和Controller组件之间的相互通信,提供了灵活高效的机制。MVC架构将其组件的表示(View)的数据对象(Model)分隔开来,但表示组件必须依赖于数据对象。一旦数据对象中发生了任何状态的改变,表示组件就应使用正确信息来渲染一个一致的视图。Observer模式描述了对这些看似矛盾的关系的解决方案,这个模式基于两个主要角色:Subject(主题)和Observer(观察者)。主题表示数据对象,可能有任意数目的观察者,后者通过一个一般性接口订阅要接收的状态改变通知。当接收到更改通知时,每个观察者可能会通过这个一般性接口来查询该主题,以便和它的状态同步。Observer模式中有许多组成部分,先概括出每个组成部分的职责,然后解释它们如何相互协作来实现模式目标。如图4.9给出了Observer模式的结构。其中Subject(主题):提供了一个一般性接口来增加和删除观察者,同时向已注册的观察者通知状态的改变。ConcreteSubject(具体主题):实现了Subject接口,并保存了观察者集合,这些观察者已注册要求被通知,它还提供了对其状态的访问。Observer(观察者):为观察者组件提供了一个一般性接口,来接收Subject状态改变的通知。ConcreteObserver(具体观察者):实现了Observer接口,并保存了Subject状态的拷贝。每次Subject通过其Observer接口通知ConcreteObserver状态改变,ConcreteObserver可以查询Subject的新状态。32 4建立WEB事件驱动模型图4.9Observer模式Figure4.9ObserverModel每个想要观察其它控件变化的控件可以通过Subject接口进行注册。实现了该接口的ConcreteSubject管理着那些请求状态改变通知的观察者控件的集合。当状态发生变化时,ConcreteSubject遍历观察者列表,通过Observer接口通知每个观察者。每个被通知的ConcreteObserver可能会再次查询ConcreteSubject来使其状态与后者一致。为实现WEB应用开发下的事件响应机制,事件处理也要遵循Java2事件模型,在这个模型中,任何对象在自身状态改变时都可以通知其他对象。状态改变的信息封装在一个事件对象中。这个模型涉及了3个参与者:事件源,事件对象和事件监听器,总而言之,事件产生时,事件源会生成一个事件对象并将它发送到事件监听器。事件源,是发生状态改变的对象。任何对象都可以是事件源。然而,事件源类必须提供方法来注册或取消注册事件监听器,这些监听器对事件源的状态改变感兴趣,同时,事件源必须维护一个感兴趣的事件监听器列表,如提供addActionListener和removeActionListener方法来增加和删除监听事件。另外,事件源也必须提供逻辑来创建事件对象并将它传递到所有感兴趣的事件监听器中,如下是一个简单事件源程序清单。publicclassMyEventSource{privateArrayListlisteners=newArrayList();……publicvoidaddEventListener(MyEventListenerlistener){33 重庆大学硕士学位论文listeners.add(listener);}publicvoidremoveEventListener(MyEventListenerlistener){listeners.remove(listener);}……}事件对象,封装事件源中的状态改变信息。例如,已改变状态的旧值和新值。事件对象的类必须扩展Java.util.EventObject类。EventObject类的getSourse方法用来返回事件源。在事件对象类中,可以实现相关事件的方法,比如通过相关方法可以得到值改变前后的内容,如getOldValue和getNewValue。现使用一个MyEventObject类来实例事件对象。程序清单如下:publicclassMyEventObjectextendsEventObject(){privateStringoldValue;privateStringnewValue;publicMyEventObject(Objectsource,StringoldValue,StringnewValue){……}……}事件监听器,接收事件源状态改变通知的对象。通过实现的监听器接口来接收特定类型的事件,所有的监听器接口都是Java.util.EventListener接口的子接口,这个接口没有任何方法,并且作为一个标记接口。因此事件监听器接口必须定义一个用来接收相应事件对象的方法。下面程序显示了MyEventListener监听器。publicinterfaceMyEventListenerextendsEventListener{publicvoidhandleEvent(MyEventObjectevent);……}根据WEB应用的特点,常出现两种类型的事件:数值改变(ValueChanged)和动作事件Action。数据改变事件用于观察用户界面控件property的改变(例如展开树节点或者修改文本框中的文字);Action事件则对观察由UICommand派生的用户界面控件(包括按钮和超链接)的激活动作非常有用。所有这些事件类型最终都可从共同祖先Event继承而来。这样WEB事件模型遵循JavaBean的规范,图4.10显示了WEB事件驱动模型中类的关系。从图中可以看出,所有的事件类都是34 4建立WEB事件驱动模型Event的子类,WEB应用支持两种事件:ActionEvent和ValueChangeEvent。对于不同的事件,使用不同的接口处理,ActionListener用来处理ActionEvent的事件,ValueChangeListener用来处理ValueChangeEvent的事件,所以事件监听器类只要实现相应的接口就可以处理不同的事件。Event<>Listener<><>ActionEventValueChangedEventActionListenerValueChangedListener图4.10WEB事件与事件监听类Figure4.10ClassesofWEBEventandListener4.2.3WEB事件分类有了WEB事件模型,在WEB下实现事件机制成为可能,但要为开发人员提供一个事件开发的编程环境,要考虑事件在不同情况下的状态。在WEB开发时,开发人员对事件编程应当如何去实现,具体需要做哪些工作;在WEB应用运行时,事件运行的过程应当是怎样,如何才能使事件正常的接收请求响应。为此,在建立WEBRAD框架时将事件分为两大状态,一类是非运行态,一类是运行态。如图4.11所示。非运行态事件运行态事事配即时事件运加事件件置行载件监对生事配源听象成件置器批量事件图4.11WEB事件分类Figure4.11SortofWEBEvent35 重庆大学硕士学位论文事件非运行态也称为事件开发态,即当开发人员在WEBRAD框架界面上对控件进行事件编程时,此时事件的状态处于非运行态,这个状态是为WEB应用提供正常事件运行的服务,只对开发人员可见。为实现WEB应用的事件机制,在开发时要实现Java的事件机制,也就是要有事件源、事件对象和事件监听器,上一小节定义的这三种对象的数据类型,因此,开发人员只需要定义事件源(如对应具体的控件)、继承事件对象并且实现监听器接口,通过一系列的相关实现,可以对某个控件响应事件。但真正在运行时还不能运行此事件,由于WEB应用中使用的是HTML语言,对应的一个个控件就是页面上的按钮,单选项等,但这些控件在HTML语言上表现为如按钮表示为,单选项表示为等,为使这些控件支持事件响应,可以在控件内注册一个ActionListener,如在按钮中增加一个属性action_listener,其值则是开发人员写的监听器的名字路径,使控件运行时通过此属性值去找匹配的监听器,因此,需要将这些配置写与配置文件,记录都对那些控件编写的事件监听程序。当WEB应用运行时所产生的事件称为事件的运行态,事件处于运行态时,为使WEB应用能执行事件响应过程,首先先加载事件的配置信息,使用各控件分别注册各自的控件事件,此后,事件就可以根据控件的请求进行响应。在事件的请求响应过程中,根据事件请求响应时间的不同,将事件分为即时事件和批量事件。即时事件是一旦某一控件的事件被触发,则立即响应此事件,将事件以HTTP的模式提交服务器,服务器处理事件返回响应信息。在此过程,事件请求响应比较及时,用户体验比较好,但如这样的事件较多时,会出现大量HTTP请求,产生大量的数据流量,将会影响服务器的效率。而批量事件是对产生的事件并不是立即进行响应,而是当用户点一个总提交时,才将页面中的所有事件进行遍历,对控件进行检查,如有事件发生,将此事件放入事件列表中进行排队,遍历完所有的控件时,统一对这些事件提交,产生一个HTTP事件请求,发往服务器,服务器根据事件队列中的事件,逐个执行,将事件的响应返回给客户端。这种批量事件常常用于值变事件,如填写表格等之类,最后提交表格的所有内容等。如图4.12所示。不管是即时事件还是批量事件,都要产生一个HTTP请求,即时事件可以使用Javascript脚本语言来产生这个HTTP请求,而批量事件使用表单的提交功能进行整体的事件提交,之后请求在服务器执行遍历控件树状态,根据控件的事件执行相应的业务,完成事件响应后,将响应的信息返回给客户端,完成事件请求。在请求处理周期中,可以为响应用户的动作而创建事件,并且所有事件都以收到它们的次序在控件生命周期的实例中排队。在控件生命周期中每个阶段最后,事36 4建立WEB事件驱动模型件可能被处理,在队列中所有事件都按照定义的阶段通知给注册的监听器。事执控件树件行检事查件请求事响应事执件件行监检事查件听器服务器批量事件响应图4.12WEB事件处理过程Figure4.12ProcessofWEBEvent从整个页面请求响应过程来看,首先使用agentservlet对请求响应进一步的封装,并对封装后的servlet构造一个对象实例,实现控件状态的保持。然后由对象实例来管理控件生命周期,对控件进行事件监听,通过相应事件处理过程,完成响应请求。WEB响应是通过处理由页面中控件触发的事件来工作的。这些事件是由用户的动作引起的。比如,当用户单击一个按钮时,按钮就会触发一个事件,通过编写监听这个事件的监听器,开发人员可以决定当特定事件发生时WEB应用应该做什么。当一个事件发生时(比如,用户单击了一个按钮),事件通知通过HTTP发往服务器。服务器端使用封装后的特殊agentservlet处理该通知。这个特殊的agentservlet能处理JSP请求的所需的一系列动作,并能对控件的状态进行监听管理,完成事件处理过程。开发人员可以不需要知道request,response和session的存在,只需实现具体的事件处理器和事务逻辑,以面向对象的方式开发自己的组件,用组件来组装自己的网页,进行快速的WEB应用开发。37 重庆大学硕士学位论文38 5建立WEBRAD开发环境5建立WEBRAD开发环境通过对快速应用开发、控件模型、事件机制等多种技术的深入研究,最终是为了建立一个便于开发人员使用的WEBRAD开发环境,由于当前开源化进程的迅速发展,决定使用Eclipse这个开源框架上的插件机制建立此WEBRAD开发环境。首先简要的介绍下Eclipse工具以及插件开发的原理。能过需求分析、功能建模和设计开发等环节,用JSF框架的底层机制,扩展用户组件,重现表示层,以达到控件拖放,代码自动生成,事件响应编程的所见即所得的快速开发环境。使开发人员真正能在像VB那样的环境下实现WEB的快速应用开发。5.1引言5.1.1Eclipse概述Eclipse是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。图5.1是Eclipse的结构图。幸运的是,Eclipse附带了一个标准的插件集,包括Java开发工具(Java[30]DevelopmentTools,JDT)。图5.1Eclipse结构图Figure5.1ArchitectureofEclipse虽然大多数用户很乐于将Eclipse当作JavaIDE来使用,但Eclipse的目标不仅限于此。Eclipse还包括插件开发环境(Plug-inDevelopmentEnvironment,PDE),这个组件主要针对希望扩展Eclipse的软件开发人员,因为它允许他们构建与Eclipse环境无缝集成的工具。由于Eclipse中的每样东西都是插件,对于给Eclipse提供插件,以及给用户提供一致和统一的集成开发环境而言,所有工具开39 重庆大学硕士学位论文发人员都具有同等的发挥场所。Eclipse最有魅力的地方就是它的插件体系结构。在这个体系中重要的概念是[31]扩展点(extensionpoints),也就是为插件提供的接口。每一个插件都是在现有的扩展点上开发,并可能还留有自己的扩展点,以便在这个插件上继续开发。如图5.2所示。图5.2Eclipse三层结构图Figure5.2ThreeLayersofEclipse由于有了插件,Eclipse系统的核心部分在启动的时候要完成的工作十分简单:启动平台的基础部分和查找系统的插件。在Eclipse中实现的绝大部分功能是由相应的插件完成的,比如WrokBenchUI插件完成界面的外观显示,ResourceManagement插件完成维护或生成项目或文件等资源管理工作,而VersionandConfigurationManagement(VCM)插件则负责完成版本控制功能,等等。虽然以上提到的每一个功能都是绝大多数IDE环境所必备的功能,Eclipse却也把它们都做成了插件模式,甚至用来开发Java程序的开发环境(Javadevelopmenttooling,JDT)也只不过是Eclipse系统中的一个普通插件而已。整个Eclipse体系结构就像一个大拼图,可以不断的向上加插件,同时,现有插件上还可以再加插件。Eclipse平台是IBM向开发源码社区捐赠的开发框架,它之所以出名并不是因为IBM宣称投入开发的资金总数4千万美元,而是因为如此巨大的投入所带来的成果:一个成熟的、精心设计的以及可扩展的体系结构。Eclipse的价值是它为创建可扩展的集成开发环境提供了一个开放源码平台。这个平台允许任何人构建与环境和其它工具无缝集成的工具。工具与Eclipse无缝集成的关键是插件。除了小型的运行时内核之外,Eclipse中的所有东西都是插件。从这个角度来讲,所有功能部件都是以同等的方式创建的。5.1.2GEF概述[32]GEF(GraphicalEditorFramework)最早是Eclipse的一个内部项目,后来逐渐转变为Eclipse的一个开源工具项目,Eclipse的不少其他子项目都需要它的支持。Eclipse3.0版本花了很大功夫在从Platform中剥离各种功能部件上,包括40 5建立WEBRAD开发环境GEF和IDE在内的很多曾经只能在Eclipse内部使用的工具成为可以独立使用的软件/插件包了。理论上我们是可以脱离Eclipse用GEF包构造自己的应用程序的,但由于它们之间天然的联系,而且Eclipse确实是一个很值得支持的开发[33]平台,所以基本上GEF还是在Eclipse中使用。GEF是一个图形化编辑框架,它允许开发人员以图形化的方式展示和编辑模型,从而提升用户体验。GEF的优势是提供了标准的MVC(Model-View-Control)结构,开发人员可以利用GEF来完成以上这些功能,而不需要自己重新设计。与其他一些MVC编辑框架相比,GEF的一个主要设计目标是尽量减少模型和视图之间的依赖,好处是可以根据需要选择任意模型和视图的组合,而不必受开发框架的局限。图5.3是GEF框架的结构。图5.3GEF结构图Figure5.3ArchitectureofGEF5.1.3JSF概述JavaServerFaces(JSF)框架技术是由JavaCommunityProcess(JCP)制定的一个Web应用框架标准,具有良好定义的请求处理生命周期和丰富的组件层次结构,旨在推动基于Java的Web用户界面开发的简易性。利用JSF提供的可重用、可扩展、基于组件的用户界面框架,在快速开发工具RAD的支持下,可以通过拖放组件的方式对Web用户界面进行可视化编辑,将用户界面产生的组件与一个数据源绑定,并将客户端用户界面产生的事件交给服务器端处理,从而大大降低基于Java的Web用户界面的开发难度,提高开发效率。JSF的Controller主要包括名为FacesServlet的前端ControllerServlet、一个或多个配置文件以及一系列Action处理器。FacesServlet负责从Web客户端接收进入请求,然后执行一组合理的步骤来准备和派发响应。步骤包括:恢复视图、应用41 重庆大学硕士学位论文请求值、处理验证、更新Model值、调用应用、渲染响应。JSF的Model指的是组件的后台数据,是一系列被声明的JavaBean。JSF的View主要是组件树。JSF的一个好处是,单个组件或者整个组件树都可以改变其渲染方式,来支持不同的客户端用户界面类型。另一个好处是,组件为Java的Web应用带来了更多的事件驱动风格。JSF组件的体系结构是这样设计的:组件的功能由组件类定义,组件的呈现由一个单独的呈现器(Renders)定义。呈现器定义了组件类如何映射为适合特定客户的组件标签。JSF参考实现中包含了一个标准的RenderKit,用于将组件类呈现给HTML客户。JSF的工作方式:JSF应用是通过处理由页面中组件触发的事件来工作的。这些事件是由用户的动作引起的。当一个事件发生时(比如,用户单击了一个按钮),事件通知通过HTTP发往服务器,服务器响应此事件,做出相应的动作,将数据返回客户端。5.1.4扩充控件库控件的数量、种类的多少影响快速开发的效率,因此一个WEBRAD应当有足够丰富的控件,除了常规的控件外(如按钮、单选框等)也需要一些常用的控件(如日历、树控件等),本文研究的WEBRAD框架是基于JSF框架上建立的,而JSF本身提供了一系列可用于JSP页面里的标准用户界面(UI)组件,将组件定义出各自的用户界面则就可转换成控件,了解这些组件及其工作原理对于实现快速应用开发是至关重要的。组件接口UIComponent定义了UI组件和JSF实现之间的协议。事实上,它是JSF技术中一个非常基本的接口,每个UI组件都必须实现此接口,无论是直接的还是间接的。JSF里的标准组件,它们全都实现了UIComponent接口,并且位于javax.faces.component包里。UIComponent接口是javax.faces.component包里的核心类型。JSF提供一个基类javax.faces.component.UIcomponentBase,其他的类可扩展该类。使用中尽量扩展UIcomponentBase类,而不是直接实现UIComponent接口,这样在UIcomponent接口将来有什么改变,可以最大程度地减小对应用的影[34]响。JSF请求是由请求里的状态信息所构建的组件树来表示的。为了在组件树里标识一个组件,每个组件都必须有用于JSF实现的处理过程的标识符。每个组件涉及到两个标识符:客户端标识符和组件标识符。①组件标识符组件标识符是指用户给定的名称,用户可以通过使用代表UI组件的标记中id特性(attribute)来给出组件标识符。UIComponent接口提供了getComponentId和42 5建立WEBRAD开发环境setComponentId方法来获取或改变组件标识符。②客户端标识符客户端标识符是JSF实现用来标识组件的名称。如果有组件标识符(比如,用户给组件提供了名称),客户端标识符就和组件标识符相同,否则,JSF实现自动生成客户端标识符。JSF实现需要使用客户端标识符是出于以下原因:作为请求参数的名称,从而在后续的请求中,JSF实现就可以识别出这个参数的输入值。作为客户端脚本或可访问性标签的锚(anchor)。同样UIComponent接口提供了getClientId方法来获取一个组件的客户端标识符。UI组件需要呈现到JSF客户端。对于使用JSF开发Web应用而言,这意味着把组件呈现为HTML标记。UI组件可以选择自己执行呈现工作,或者是把这个工作委托给外部的Renderer。所有JSF附带的标准UI组件都把此工作委托给外部的Renderer。Renderer上有decode、encodeBegin、encodeChildren及encodeEnd方法,JSF实现会在请求处理生命周期中调用这些方法。在应用请求值阶段,它会调用decode方法,从FacesContext实例的请求里取得UICompent的当前状态。JSF尝试把这些状态信息转换成组件的本地值。而在呈现响应阶段,则会调用[35]encodeBegin、encodeChildren和encodeEnd方法来完成呈现组件的任务。由于标准UI组件使用外部的Renderer,所以不需要为这些方法提供实现。如果一个UI组件自己处理组件呈现工作,它的RendererType属性的值应为null,并需要为以上各方法提供实现。JSF标准已为底层实现了事件响应的机制,但是JSF并没有像想象中那样在业界流行开来,其实JSF最大的问题在于,没有像ASP.net那样丰富的IDE支持。JSF只是一个标准,它只是提供了一个不错的框架和一些基础的不能基础的组件,很显然别指望直接使用最基本的JSF来完成什么开发,多数用户设计者都需要更高级的一些组件,例如日历、页签式嵌板或导航树,它们不属于标准JSF组件集,幸运的是,JSF使得创建可重用的具有丰富功能的JSF组件成为可能。JSFAPI允许实现自定义组件和相关的标签,其功能与JSF标准标签一样。例如,h:input使用值绑定来将文本字段的值与bean属性相关联,当值变化时,JSF标准输入组件会触发值变化事件。建立自己的组件主要包括三个部分:UIComponent子类、Renderer和自定义组[36]件标记。并不是所有自定义组件都要求写这三部分,因此对JSF的组件扩展有两种方法,一是对现有的组件进行扩充,一是从头开发一个新组件。通过对现有的组件进行扩充,以获得一个行为被略为调整的新组件。一般情况下这种做法已经足以应付绝大部分的需要,但对于复杂的需求可以定义一个全新组件,以便在使用中提供方便,本小节以树状控制组件为例,说明如何现实一个全新的组件,43 重庆大学硕士学位论文其它相似的组件的扩充可以举一反三。树状控制组件的外观是一个树状组织结构,除了叶节点之外的每一个节点都可以展开或收缩。要做到树状控制组件的效果,至少要制作三样东西:一个自定义―组件‖、一个自定义―绘制器‖以及一个自定义的数据模型。此外,若要搭配JSP网页,则还必须准备一个自定义动作组件(即taghandler)。自定义动作组件创建tree组件,并将它关联到treerenderer。树状结构中的三种不同类型节点,分别以三个名称分别为openNode、closedNode和leafNode的facet组件来处理。对于前两者,使用动作标记,它内嵌一个可绘制出文件夹图标的动作标记以及一个可绘制出节点名称的动作标记。对于叶节点,使用一组动作组件来绘制出节点名称与值。被当成facet使用的组件,可通过动作标记的var属性所定义的变量来访问当前的TreeNode实例。此外,它们也可以通过varNodeToggler属性所指的bean,访问到该bean提供的动作方法。那个bean提供了一个方便的动作方法,可依节点当时的现况(展开或闭合)来改变下次绘制时的状态。Tree组件所用的模型类是com.mycompany.jsf.model.TreeModel。它提供访问一棵由TreeNode实例构成的树状结构的任意节点的能力。packagecom.mycompany.jsf.model;publicclassTreeModel{privatefinalstaticStringSEPARATOR=String.valueOf(NamingContainer.SEPARATOR_CHAR);privateTreeNoderoot;privateTreeNodecurrentNode;publicTreeModel(TreeNoderoot){this.root=root;}publicTreeNodegetNode(){returncurrentNode;}publicvoidsetNodeId(StringnodeId){if(nodeId==null){currentNode=null;return;}44 5建立WEBRAD开发环境TreeNodenode=root;StringBuffersb=newStringBuffer();StringTokenizerst=newStringTokenizer(nodeId,SEPARATOR);//Trowawaytherootindexsb.append(st.nextToken()).append(SEPARATOR);while(st.hasMoreTokens()){intnodeIndex=Integer.parseInt(st.nextToken());sb.append(nodeIndex);try{node=(TreeNode)node.getChildren().get(nodeIndex);}catch(IndexOutOfBoundsExceptione){Stringmsg="NodenodewithID"+sb.toString()+".Failedtoparse"+nodeId;thrownewIllegalArgumentException(msg);}sb.append(SEPARATOR);}currentNode=node;}}TreeModel构造函数需要一个代表树状结构根节点的TreeNode为自变量,它会将该参照指针存入自己的实例变量。setNodeId()方法将当前节点设定为nodeID所指的节点。NodeID是一个以冒号分隔的节点索引字符串,例如,―0:0:1‖代表―根节点的第一子节点的第二子节点‖。如果没有任何节点被选中的话,则getNode()方法返回当前节点或null。UITree组件类是tree组件的具体实现,其设计很类似于标准的UIData组件。它使用一组定义成facet的组件来绘制出模型里的所有实例。在请求处理周期的每一阶段,它会遍历一次树状结构里的每一个节点,重复调用节点组件的setNodeId()方法,并通过一个requestscope变量释放出当前节点,然后要求适当的facet来处理它。UITree与UIDate之间的主要差异,是前者使用的数据模型是树状结构,而后者使用的结构是由行与栏构成的表格。45 重庆大学硕士学位论文绘制器TreeRenderer类是继承Renderer类,而且它的getRendersChildren()方法必须返回true,因为它自己控制了UITree组件的子组件的绘制工作。自定义组件都需要在faces-config.xml配置文件里注册。同样,对于每一对component/renderer的组合,我们需要各写一个自定义动作组件的taghandler类,使得该组合可被用于JSP网页。并且必须在标记库的TLD中声明这个taghandler。5.2系统分析与设计5.2.1开发环境功能分析此开发环境主要是为开发人员提供一种界面友好的可视化的快速开发WEB应用的开发环境,开发人员通过WEBRAD开发环境能够方便快捷地拖放可重用控件来定制界面,然后对控件进行事件编程,并且通过配置数据持久化就可以生成一套WEB应用,从而减少大量的重复性劳动,提高了开发效率。为实现此开发环境应当满足以下功能:①能支持WEB应用快速开发开发环境的Eclipse插件集。②实现窗体资源管理③能实现页面编辑数据模型④能实现控件的拖放机制⑤能实现控件事件机制⑥能实现部分代码的自动生成⑦能实现数据持久化⑧能实现WEB应用的配置部署⑨能实现WEB项目的向导生成本开发环境主要能实现以上这些功能,同时开发环境也是一个符合MVC设计模式的框架,可以从视图、控制和模型三层来分析,视图主要是呈现所编辑的页面,包括页面上的控件,在视图中其实没有真正的处理发生,作为视图来讲,它只是作为一种输出数据并允许用户操纵的方式。它可以访问模型的数据,却不了解模型的情况。当模型发生改变时,视图会得到通知,它可以访问模型的数据,但不能改变这些数据,一个模型可以由多个视图,而一个视图理论上也可以与不同的模型关联起来;模型是对应界面所建立的模型,每一控件都有它独自的模型相对应,模型是对控件的业务流程/状态的处理以及业务规则的制定,主要是对数据持久层操作。业务流程的处理过程对其它层来说是黑箱操作模型接收视图请求的数据,并返回最终的处理结果;而控制则是为模型和视图建立的一种通信机制,为从用户接收请求,将模型与视图匹配在一起,共同完成用户的请求。控制器的46 5建立WEBRAD开发环境作用很明显,它就是一个分发器,选择什么样的模型,选择什么样的视图,可以完成什么样的用户请求。控制层不做任何的数据处理,它只把用户的信息传递给模型,告诉模型做什么,选择符合要求的视图返回给用户。具体如图5.4所示。模模模模模模模模模模模模模模图5.4框架应用结构图Figure5.4FrameworkApplicationArchitectureOverview5.2.2开发环境结构设计由功能需求可以看出,开发环境体系结构可以分为几个大的模块,如图5.5所示。①界面交互模块界面交互模块主要是实现控件的拖放管理,实现控件编程的所见即所得,前层为展示层,后层为逻辑编程区,实现如VB那样的编程模式。主要是通过扩展org.eclipse.ui.views,实现Eclipse中视图的建立;扩展org.eclipse.ui.editors,实现编辑窗的建立;扩展org.eclipse.ui.perspectives,实现透视图的建立;扩展org.eclipse.ui.newWizards,实现向导的建立;扩展org.eclipse.ui.actionSets,实现主菜单栏和工具栏选项的建立。②页面编辑模块此模块主要是使用GEF框架来实现页面编辑模型,并对控件进行管理,设置控件的各种属性、方法,也可由此模块增加自定义的控件,运行时将放置页面的控件进行统一的管理,形成控件树,以便管理控件的生命周期,根据不同事件逻辑生成或销毁相应的控件。并且在页面中对控件实现事件机制,也就是实现页面的每一次响应请求都当作一个事件来处理,控件所有的动作都当一个事件,根据事件所做的动作,调用相应的逻辑,从而更新页面内的控件,完成事件响应。事件主要包括鼠标动作和值变化,对这些事件加以统一管理,按照不同的事件分类。③数据持久化模块数据持久化模块是将WEB应用中与数据表示有关系的模型持久化,如从数据库提取出数据之类,将这些数据进行对象持久化,实现快速的持久化处理。本开47 重庆大学硕士学位论文发环境使用开源的Hibernate技术实现数据持久化,开发人员可以通过快速向导配[37]置数据持久化。④生成模块此生成模块主要是负责项目中的自动生成过程,以减少开发人员的重复劳动。主要包括代码自动生成、项目构建器生成两部分。代码自动生成是对一些重复的代码通过JET框架自动生成,如页面的代码生成、事件框架代码生成等。项目生成是对一个WEB项目在新建时生成必要的工程文件、配置文件以及源码目录、编译目录等相关的执行活动。配置生成主要是在项目开发过程中每一次的资源的变动,都要在配置文件中加以修改使项目得及时的跟进,比如说新增了一个javabean文件,要让配置文件中加上对此javabean的描述;或对一个控件改变了其中的属性或方法,相当的要让配置文件中对些控件的描述加一个更改。⑤部署WEB应用模块WEB应用生成以后,我们要把它部署到相应的WEB服务器。由WEB服务器根据相应的容器来实施这个应用。WEBRAD框架界面交互页面编辑生成模块部署模块数据持久化WH可项页页代Eib开页项B视e项目大面面码r发面目持n目透管纲编控组自构项久ate向理视辑件动目视制建化导视图视模生部实图器器配图图型成署现置图5.5框架结构图Figure5.5FrameworkArchitectureOverview5.2.3开发环境①系统开发环境:操作系统:windowsXp开发工具:eclipse3.148 5建立WEBRAD开发环境开发语言:JAVA,JDK1.5Web服务器:Tomcatv5.5数据库:Mysqlv5.0②系统测试环境:操作系统:windowsXp,windows2000,linuxWeb服务器:Tomcatv5.5WebLogic8.0数据库:Sqlserver2000,Mysqlv5.0注意:在使用Mysqlv5.0做为数据库服务器时,存在字符集不兼容的问题,要先配置好MySql的字符集为UTF-8。5.3建立WEBRAD开发环境本开发环境通过Eclipse的插件系统来实现,故对此可分成几块来实现:①核心插件core,它为所有插件的基础,其他插件都直接或间接依赖于核心端,包含如JSF包、环境包等,把其他插件需要使用的功能放在核心端,提高代码的复用性。②界面插件ui,提供开发开发环境界面的展示,这是插件的最外层插件,会直接或间接的依赖于其他插件。③JSF编辑器插件jsfeditor,提供了可视化的编辑功能,它依赖于核心端。④代码生成插件codegenerator,把开发环境中所有代码生成的功能放在代码生成插件中,它负责生成页面的代码和部分JAVABEAN。⑤数据持久化插件datebase,提供了数据库连接和数据表导入导出的功能。⑥发布插件deploy,为开发环境开发的工程提供工程发布部署的功能。⑦帮助插件help,帮助插件提供了RAD开发环境的帮助文档。这些插件的依赖关系如图5.6所示uicodedatabasegeneratorcoredeployhelpjsfeditor图5.6插件依赖关系Figure5.6dependencyofPlug-ins49 重庆大学硕士学位论文5.3.1RAD环境界面的实现根据开发环境的需求,需要扩展Eclipse现有的功能,实现基于Eclipse的框架界面。要实现的开发环境界面有向导、视图、编辑器、菜单等。具体界面分成如下几个部分:①创建向导创建向导可以方便用户快速的创建工程,建立源文件、目标文件,通过扩展[38]―org.eclipse.ui.newWizards‖扩展点,建立新类ApplicationWizard类,使用addPages()方法来添加向导页面,本向导共有两个页面,第一个为定制的信息向导页,可以在此向导页面创建包括工程名称、作者、公司等基本信息;第二个为创建Java工程的页面,在此向导页面创建源文件夹、目标文件夹和输出Web目录,此页面继承于JDT的JavaCapabilityConfigurationPage类,用于创建Java工程,其中―updateProject‖方法用于初始化创建Java工程的环境。如图5.7所示。同时在创建工程向导中,创建类路径加载入口Core,JDT在构建类路径时会根据Core加载JAR包。具体plugin.xml内扩展点实现代码如下:50 5建立WEBRAD开发环境图5.7项目向导图Figure5.7ProjectWinzard②RAD开发环境透视图透视图(Perspectives)是Eclipse中的一个概念,它代表一个视图和编辑窗口的集合。每组不同的插件要完成的功能不一样,要打开的视图及编辑器窗口也就不一样,打开框架开发环境首先显示的所有视图的组合为透视图。通过扩展透视图能够控制你打开的视图及编辑器。在快速开发框架中,我们要展现的视图有项目资源管理器视图、页面编辑器和大纲视图。快速开发工具透视图通过扩展Eclipse的org.eclipse.ui.perspectives扩展点实现。此扩展点用来将透视图工厂添加至工作台。透视图工厂用来定义透视图的初始布局和可视操作集。用户可通过调用―窗口‖菜单的―打开透视图‖子菜单来选择透视图。当用户在任务之间移动时,他们可以在透视图之间进行切换。透视图定义视图集合、视图布局和用户首次打开透视图时应使用的可视操作集。Perspectives在Plugin.xml文件中的定义为:class="cn.edu.cqu.rad.ui.perspective.RADPerspectiveFactory"name="RAD"id="cn.edu.cqu.rad.ui.RADPerspective"/>③其它相关视图1)项目管理视图项目管理器的主要功能是管理快速开发工具新建的项目。通过树型结构把快速开发工具建立的项目展现出来,并维护项目的整个开发周期。项目管理器功能包括如下几个部分:新建项目、生成WEBJSF应用、部署WEB应用和删除项目等。51 重庆大学硕士学位论文项目管理器视图通过扩展Eclipse的org.eclipse.ui.views扩展点实现。此扩展点用来为工作台定义更多视图。视图是工作台页面内的可视控件,通常用来浏览信息的层次结构(例如,工作空间)、打开编辑器或显示活动编辑器的属性。用户能从―视图‖菜单中看见视图,或者从视图本地标题栏中关闭视图。视图是可以浏览信息层次结构或显示对象属性的工作台部件。在一个工作台页面中,只能打开任何给定视图的一个实例。当用户在视图中进行选择或做其它更改时,这些更改会立即显示在工作台中。提供视图通常是为了支持相应的编辑器。View扩展点在Plugin.xml文件中的定义为:通过项目管理器菜单能对当前选择的结点进行相应的操作。主要完成下面几个部分的操作:a.新建:新建工程、新建配置、新建JSF页面。b.生成:生成页面编码、生成配置和生成WEB应用。c.部署:部署生成的WEB服务。项目管理器菜单是通过Eclipse的MenuManager类实现,通过JFace的TreeView实现树型结构。项目管理器菜单的实现代码如下:privatevoidhookContextMenu(){52 5建立WEBRAD开发环境//通过内部类实现MenuManager类MenuManagermenuMgr=newMenuManager();menuMgr.setRemoveAlIWhenShown(true);menuMgr.addMenuListener(newIMenuListener(){publicvoidmenuAboutToShow(IMenuManagermanager){fillContextMenu(manager);}});//建立上下文菜单Menumenu=menuMgr.createContextMenu(treeViewer.getControl());//把上下文菜单挂到树型结构上treeViewer.getControl().setMenu(menu);getSite().registerContextMenu(menuMgr,treeViewer);}2)大纲视图大纲视图的主要功能是建立页面模型和控件模型的联系,并按照页面控件的主子关系展现成树型结构。Eclipse的大纲视图不是通过实现相应的扩展点实现的,而是通过Adapter(适配器)动态适配的,Eclipse的大多数核心类都实现IAdaptable接口,能通过IAdaptable接口的getAdapter方法动态适配接口不相容的对象。Eclipse的编辑器中通过getAdapter方法得到编辑器相关联的大纲视图,如以下代码所示。publicObjectgetAdapter(Classtype){If(type==IContentOutlinePage.class)returnnewOutlinePage();returnsuper.getAdapter(type);}其中,IContentOutlinePage接口的对象表示大纲视图,但GEF不直接实现IContentOutlinePage接口,而是通过实现它的子类ContentOutlinePage完成大纲视图,我们通过继承ContentOutlinPage类实现GEF相关的大纲视图。3)页面编辑视图页面编辑器来实现JSF页面的编写,此编辑器涉及的内容较多,具体的实现见下一小节说明。5.3.2页面编辑器的实现在快速开发工具中,页面编辑器是重要一部分,主要实现页面的可视化编程,53 重庆大学硕士学位论文页面编辑器由多页面签组成,具体由三个页面签,一个是页面代码显示,一个是页面视图显示,一个是后台JAVA类显示,在页面视图上还有一个选项板的视图,选项板主要是可视控件的排列,如表单、按钮等控件。用户可以将控件从选项板控件面板中拖放到界面编辑器中,并能够对控件进行移动、删除、修改等操作,为了使得开发人员能够更加容易地对控件进行布局,编辑器必须提供对选定的多个控件进行对齐(上下左右4个方向)、等宽、等高等操作。当用户将控件从控件面板中拖放到界面编辑器的时候,编辑器必须为控件提供一个默认的ID,此ID不能与其他控件的ID重复;用户可以修改生成的ID,但是修改后的ID同样不能与其他控件的ID重复。当用户对界面进行修改并且可以保存,后台的Java代码也执行相应的保存操作,当用户选中菜单中的生成项后,会调用代码生成机制生成对应的JSF代码。①页面模型设计实现页面编辑器是用GEF框架来实现,而构造一个GEF应用程序通常分为这么几步:设计模型和Editor、设计EditPart和Figure、设计EditPolicy和Command。其中EditPart是最主要的一部分,而实现它的时候不可避免的要使用到EditPolicy,而后者又涉及到Command。1)设计模型与Editor模型是根据应用需求来设计的,所以我们的模型包括代表整个图的FormDiagram和代表总控件的Control以及其它众多的控件,子控件按名称来区分,如按钮控件使用ButtonControl,单选框控件使用SelectControl等。模型是要负责把自己的改变通知给EditPart的,为了把这个功能分离出来,使用名为Element的抽象类专门来实现通知机制,然后让其他模型类继承它。Element类里包括一个PropertyChangeSupport类型的成员变量,并提供了addPropertyChangeListene()、removePropertyChangeListener()和fireXXX()方法分别用来注册监听器、删除监听器和通知监听器模型改变事件。为实现能在属性视图编辑模型属性,模型要实现IPropertySource接口,可以通过一系列的get和set方法来编辑属性,这样就可以在属性视图中编辑控件属性。在GEF里,模型的监听器就是EditPart,在EditPart的active()方法里我们会把它作为监听器注册到模型中。在此RAD开发环境中,也要使用GEF应用程序实现Editor,为用户提供一个可视化的编程环境。Editor继承于GraphicalEditorWithFlyoutPalette类,表示它是一个具有自动隐藏包含控件选项板的图形编辑器。最重要的两个方法是configureGraphicalViewer()和initializeGraphicalViewer(),分别用来定制和初始化EditPartViewer。在GraphicalEditor类里会先后调用这两个方法,只是中间插了一个hookGraphicalViewer()方法,其作用是同步选择和把EditPartViewer作为54 5建立WEBRAD开发环境ISelectionProvider注册到所在的Site(Site是Workbench的概念)。所以,与选择无关的初始化操作应该在前者中完成,否则放在后者完成。这个Editor是一个带有包含控件选项板的可视化编辑器,所以要告诉GEF选项板里都有哪些控件,这是通过覆盖getPaletteRoot()方法来实现的。在这个方法里,利用自己写的一个工厂类PaletteFactory构造一个PaletteRoot对象并返回。选项板里对控件分两大类,一种是JSF_Basic控件(JSFBasicControl),主要是一些HTML常用控件;一种是JSF_Form控件(JSFFormControl),主要能实现表单功能的控件。在GEF里,选项板里可以有抽屉(PaletteDrawer)把各种控件归类放置,每个工具都是一个ToolEntry。选项板的初始化操作放在initializePaletteViewer()里完成,最主要的任务是为选项板所在的EditPartViewer添加拖动源事件支持。前面已经为EditPartViewer添加了拖动目标事件,所以现在就可以实现完整的拖放操作。2)构造Command建立好模型和Editor后,因为模型的改变都是由Command对象直接修改的,所以创建Command是必须的。它们之间的调用关系如图5.8所示。由需求可知,我们对模型的操作有增加控件、删除控件、修改控件名称和改变控件位置、属性等,所以对应就有CreateControlCommand、DeleteControlCommand、RenameControlCommand、MoveControlCommand、ChangeLocationCommand这些对象。它们都放归类在―commands‖包里。一个Command对象里最重要的当然是execute()方法,也就是执行命令的方法。除此以外,因为要实现―撤消/重做‖功能,所以在Command对象里都有Undo()和Redo()方法,同时在Command对象里要有成员变量负责保留执行该命令时的相关状态。例如RenameControlCommand里要有oldName和newName两个变量,这样才能正确的执行Undo()和Redo()方法。每个被执行过的Command对象实例都是被保存在EditDomain的CommandStack中的。3)构造EditPolicyEditPart(控制器)中通过createDeleteCommand()方法添加EditPolicy(编辑策略),每种EditPolicy负责处理相应的请求。EditPart会遍历所有的EditPolicy处理请求,每种类型的EditPolicy关心特定的请求,而忽略其他的请求。每个EditPart都可以设置多个EditPolicy,通过EditPolicy,控制器能够处理多种类型的请求,开发环境所有的控件器都与图形有关,请求使用创建模型、删除模型、移动模型、嵌套模型和改变模型属性等。55 重庆大学硕士学位论文图5.8请求通讯链Figure5.8CommunicationchainRequest4)构造EditPart有了Command和EditPolicy,现在可以来看看EditPart部分。每一个模型对象都对应一个EditPart,所以有两个模型对象(Element不算)分别对应DiagramPart和ControlPart。对于含有子元素的EditPart,必须覆盖getModelChildren()方法返回子对象列表,例如ControlPart里这个方法返回的是Control对象包含的所有Control对象列表。每个EditPart都有active()和deactive()两个方法,一般我们在前者里注册监听器(因为实现了PropertyChangeListener接口,所以EditPart本身就是监听器)到模型对象,在后者里将监听器从列表里移除。在触发监听器事件的propertyChange()方法里,一般是根据―事件名称‖决定使用何种方式刷新视图。例如对于ControlPart,如果是控件本身的属性发生变化,则调用refreshVisuals()方法,这里用到的事件名称都是我们自己来规定的。EditPart的另外一个需要实现的重要方法是createFigure(),这个方法应该返回模型在视图中的图形表示,是一个IFigure类型对象。一般都把这些图形放在―figures‖包里。Diagram对象对应的是GEF自带的名为FreeformLayer的图形,它是一个可以在东南西北四个方向任意扩展的层图形;而Control对象是一个抽象的对象,它所有的子对象均对应于GEF自带的图形,如按钮对象ButtonControl对应的是GEF自带的Button图形。56 5建立WEBRAD开发环境最后,要为EditPart增加适当的EditPolicy,这是通过覆盖EditPart的createEditPolicies()方法来实现的,每一个被―安装‖到EditPart中的EditPolicy都对应一个用来表示角色(Role)的字符串。对于在模型中有子元素的EditPart,一般都会安装一个EditPolicy.LAYOUT_ROLE角色的EditPolicy,后者多为LayoutEditPolicy的子类。图5.9EditPart对象Figure5.9EditPartObject用户的操作会被当前工具(缺省为选择工具SelectionTool)转换为请求(Request),请求根据类型被分发到目标EditPart所安装的EditPolicy,后者根据请求对应的角色来判断是否应该创建命令并执行。如图5.9所示。Role-EditPolicy-Command这样的设计主要是为了尽量重用代码。例如同一个EditPolicy可以被安装在不同EditPart中,而同一个Command可以被不同的EditPolicy所使用,等等。当然,凡事有利必有弊,普遍认为这种的设计也有缺点,首先在代码上看来不够直观,你必须对众多Role、EditPolicy有所了解,从而增加了学习周期;另外大部分不需要重用的代码也要按照这个相对复杂的方式来写,从而带来了额外工作量。②实现页面编辑器下面将利用GEF框架构造模型编辑器用JSFEditor继承于GraphicalEditor类,页面编辑器主要由如下几个部分组成。1)编辑器的初始化在插件的扩展点中,使用cn.edu.cqu.rad.editors.MultiPageEditor类实现了org.eclipse.ui.editors扩展点中MultiPageEditorPart类,即JSFEditor类负责对模型编57 重庆大学硕士学位论文辑器的初始化等一系列的操作。通过重载creatPages()方法实现多页签,代码如下。protectedvoidcreatePages(){createJSFPage();createHtmlPage();createJavaPage();}JSFEditor要完成的工作主要有如下几个方面:a.GEF框架的初始化。b.模型、控制器和视图的初始化。c.属性视图初始化。d.资源监听器的实现。e.面板的初始化。f.获得大纲实例。2)模型的实现GEF模型可以理解成一个简单的可持久化的实体,模型只与控制器打交道,而不知道任何与视图有关的东西。为了能让控制器知道模型的变化,应该把控制器作为事件监听者注册在模型中,当模型发生变化时,就触发相应的事件给控制器,后者负责通知各个视图进行更新。典型的模型对象会包含PropertyChangeSupport类型的成员变量,用来维护监听器成员即控制器。对于与其他对象具有嵌套关系的模型,要维护连入/连出的嵌套列表。控件模型对应的控件具有大小和位置信息,还要维护它们。这些变量并不是模型本身必须的信息,维护它们使模型变得不够清晰,但可以通过构造一些抽象模型类来维持它们的可读性。3)视图的实现GEF的视图可以有很多种,GEF目前提供了图形(GraphicalViewer)和树状(TreeViewer)这两种,前者利用Draw2D图形(IFigure)作为表现方式,多用于编辑区域,后者则多用于实现大纲展示,如果要表现模型,控制器都会为模型创建对应的视图。视图是可以复用的,例如,如果有不同的文本控件模型,分别表示整形、日期型和字符型等模型,它们的区别在于显示图标和显示文本,则控制器在创建视图时可以用同一视图类,设置不同的显示图标和显示文本即可。视图的任务同样繁重,除了模型的显示功能以外,还要提供编辑功能、回显(Feedback)功能和工具提示(ToolTip)功能等等。在RAD开发环境中,视图的实现是由不同的类来实现的,这些不同的类都继承于Figure类。Figure类是GEF提供的视图编辑类,它封装了最基本的视图显示58 5建立WEBRAD开发环境方式,在应用中一般都可以重用Figure来实现同一类视图。4)控制器的实现在MVC结构里控制器是模型与视图之间的桥梁,也是整个GEF的核心。它不仅要监听模型的变化,当用户编辑视图时,还要把编辑结果反映到模型上。例如,用户在页面上画一个按钮,控制器应该从模型添加这个按钮对象,相反则删除这个按钮对象以及与这个对象有关的所有连接。GEF中的控制器是所谓的EditPart对象,更确切的说应该是一组EditPart对象共同组成了GEF的控制器这部分,每一个模型对象都对应一个EditPart对象。你的应用程序中需要有一个EditPartFactory对象负责根据给定模型对象创建对应的EditPart对象,这个工厂类将被视图利用。用户的编辑操作被转换为一系列请求(Request),有很多种类的请求,这些种类在GEF里被称为角色(Role),GEF里有图形化和非图形化这两大类角色,前者比如LayoutRole对应和布局有关的操作,后者比如ConnectionRole对应和连接有关的操作等等。角色这个概念是通过编辑策略(EditPolicy)来实现的,EditPolicy的主要功能是根据请求创建相应的命令(Command),而后者会直接操作模型对象。对每一个EditPart,你都可以―安装‖一些EditPolicy,用户对这个EditPart的特定操作会被交给已安装的对应EditPolicy处理。这样做的直接好处是可以在不同EditPart之间共享一些重复操作。在模型编辑器中,所有的EditPart都是从RADBaseEditPart继承过来的,RADBaseEditPart继承于AbstractGraphicalEditPart,这个EditPart是由GEF框架提供的,它封装了最基本的图型编辑框架的事件通知机制。publicabstractclassRADBaseEditPartextendsAbstractGraphicalEditPartimplementsControlEditPart,PropertyChangeListener{//注册PolicyprotectedvoidcreateEditPolicies(){installEditPolicy(EditPolicy.COMPONENT_ROLE,newRADEIementEditPolicy())installEditPolicy(EditPolicy.GRAPHICALNODE_ROLE,newRADControlEditPolicy());}publicvoidpropertyChange(PropertyChangeEventevt)refreshVisuals();}//刷新视图59 重庆大学硕士学位论文protectedvoidrefreshVisuals(){…}//注册监听器publicvoidactivate(){if(isActive())return;super.activate();getRADEieldBase().addPropertyChangeListener(this);}//删除监听器publicvoiddeactivate(){if(!isActive())return;getRADEieldBase().removePropertyChangeListener(this)super.deactivate();}…}5)Action的实现Action模块的主要功能是提供模型的双击事件、复制、剪切、删除和粘贴的操作。双击事件:双击事件操作是由RADDoubleAction类实现。双击事件功能实现是打开页面编辑器的JAVA代码编辑器进行后台代码编辑,打开的过程自动生成以该控件为命名的唯一的类名,代码如下。this.getControl().addMouseListener(newMouseAdapter(){publicvoidmouseDoubleClick(MouseEvente){handleDoubleClick();}});复制:复制操作由RADCopyAction类实现。KDECopyAction继承于SelectionAction类,它的功能是通过GEF的剪切板Clipboard把当前选定的EditPart的引用拷贝到剪切板中。剪切:剪切操作由RADCutAction类实现。剪切功能和复制功能类似,但剪切功能会删除当前容器中对应的EditPart。60 5建立WEBRAD开发环境粘贴:粘贴操作由RADPasteTemplateAction类实现。粘贴功能实现的操作比较复杂,它通过剪切板得到当前的剪切板中EditPart的引用,然后把EditPart中的模型及子模型克隆成新的模型加入到容器中。6)EditPolicy的实现EditPolicy在GEF是一个比较重要的概念。当一个EditPart加载的时间,都会通过覆盖EditPart的createEditPolicies()方法来实现的自己的EditorPolicy。GEF框架封装了常用的EditPolicy,通过扩展继承这些Policy,可以实现模型编辑的相应操作。在EditPart的createEditPolioies()中,可以通过inatallEditPolioy(role,editorPolioy)来加载你自己的EditPolicy。通过EditPart基类,可以看到当相应的Policy存在时,会用最后的Policy进行处理,并激活此Policy。7)Command的实现GEF中模型的改变都是由具体的Command操作实现。通过Command我们还能重复和撤消模型的操作,这都是由Command设计模式负责的,我们要在Command模式中实现相应的REDO和UNDO代码。下面是创建一个模型的REDO和UNDO代码。在Command中GEF框架封装了最底层的Command执行,重复和撤消的操作。在快速开发工具中,由于要实现的是关系模型数据表的编辑,所以涉及到的Command有如下一些:CreateCommand:负责模型的建立。AddCommand::负责模型的拖放加入。CloneCommand:负责模型的克隆。NestedCommand:负责模型的嵌套。CutDeleteCommand:负责模型的剪切并删除。DeleteCommand:负责模型的删除。8)Role的实现Role是个字符串的常量,是用来做Policy中的标识用的,但某一种类型的Policy被加装后,EditPart会根据Role来区分不同的Policy,如果不同的Policy使用同一个Role,后者将覆盖前者。在本系统中,我们采用了系统的Role来注册我们的Policy。9)选项板的实现GEF是一个图形编辑框架,它的主编辑区域是一个图形的视图,另外,用户还可以选择选项板上相应的模型,把选择的模型对应的视图加入到图形编辑区域进行编辑。在GEF中,图形编辑器实现类的getPaletteRoot方法将返回一个61 重庆大学硕士学位论文PaletteRott对象,用户可以PaletteRoot中添加模型选项入口项(ToolEntry),入口项的参数述了选项板中选项的显示标签、显示图标、提示信息、模型的模板类及模型的创建工厂类等信息。本开发环境的选项板主要是放置一些供开发人员快速开发实现的控件,如按钮、表单等。5.3.3数据持久化的实现数据持久化,即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的数据存储在关系型的数据库中,当然也可以存储在磁盘文件中、XML数据文件中等等。在WEB应用中也一个常见的概念,在过去的三层软件结构逐渐转变为业务逻辑层增加一持久化层的四层软件结构,过去业务逻辑层不仅负责业务逻辑,而且直接访问数据库,提供对业务数据的保存、更新、删除和查询操作。为了把数据访问细节和业务逻辑分开,把数据访问作为单独的持久化层。Hibernate就是一种实现持久化的对象关系映射工具,本开发环境的数据持久化使用Hibernate插件来实现数据持久化。Hibernate作为中间件,可以为任何一个需要访问关系数据库的Java应用服务,是连接Java对象模型和关系对象模型的桥梁。作为Hibernate的使用者,无需关心它是如何实现的,只需要知道如何访问它的接口就行了。本开发环境使用开源的HibernateSynchronizer来实现数据持久化,HibernateSynchronizer是一个Eclipse插件,可以自动生成*.hbm文件、持久化类和DAOs。HibernateSynchronizer的功能包括:通过一个向导配置并生成HibernateConfigurationFile;通过一个向导同步生成数据库表的*.hbm文件;通过*.hbm文件同步生成Hibernate持久化类和DAOs;提供HibernateSynchronizereditor编辑*.hbm文件;用一种叫做Velocity的语言定制个性化的代码和资源生成模板(通常没有必要)。向导配置如图5.10所示。图5.10Hibernate配置Figure5.10HibernateConfiguration5.3.4生成与部署模块的实现①生成模块的实现生成模块主要分以下几个部分,一个是代码的自动生成,一个是构建器,1)代码的自动生成62 5建立WEBRAD开发环境我们开发程序的过程中,特别是开发一些业务系统的过程中,一些重复的代码总是不可避免的,这些工作如果要开发人员去手动完成话,不仅会降低开发效率,而且会带来很多bug,最重要的是极容易使得开发人员产生厌倦心理从而消极怠工甚至离职,从而提高了项目的人力资源成本、增大了项目的风险。因此在大一些的开发团队中都在使用着各种或公开或自制的代码生成工具,而且越来越多的人开始选择自制工具,这是因为使用第三方的代码生成工具往往不能满足自己的个性化需求。我们可以通过多种方式来写代码生成工具,比如最简单的通过StringBuffer拼字符串,或者借助Groovy、Template、Velocity等工具来完成,这些工具各有千秋,在工具Eclipse中有以下代码生成方案。a.使用StringBuffer拼接来生成代码在一些比较简单的代码生成中,这样的方式是比较方便的,但是当生成的代码结构变得越来越复杂的时候,代码中stringbuffer.append()与逻辑判断代码搅和在一起,程序变得非常难以维护。b.使用JDTAPI中的ASTJDT会把Java代码编译成AST(AbstractSyntaxTree抽象语法树),这样复杂的Java代码就变成了相对简单的树状结构,我们就可以通过AST来遍历Java代码,从而解析代码或者对代码进行修改,Eclipse中的Java代码重构就是基于AST来进行的。在Eclipse中AST被称为CompilationUnit,对应的接口就是ICompilationUnit,通过Java代码来生成CompilationUnit最简单的方法是使用IPackageFragment.createCompilationUnit。指定编译单元的名称和内容,于是在包中创建了编译单元,并返回新的ICompilationUnit。我们还可以从头创建一个CompilationUnit,即生成一个不依赖于Java代码的CompilationUnit,然后在这个CompilationUnit上添加类、添加方法、添加代码,然后调用JDT的AST解析器将CompilationUnit输出成Java代码。这种方式是最严谨的方式,但是当要生成的代码比较复杂的时候程序就变得臃肿无比,而且只能生成Java代码,不能生成XML配置文件等文件。c.使用JETJET是Eclipse中一个非常强大的代码生成工具,使用JET你可以运用类似JSP一样的语法,这样我们就可以轻松地编写代码模板。用它可以创建SQL语句、XML、Java源代码等文件的代码生成器。因此本开发环境将把它作为代码生成的工具,因此我们在此处重点讲解JET的使用。JET是EMF(EclipseModelingFramework)框架的一部分,要使用它必须首先安装EMF插件。63 重庆大学硕士学位论文使用JET分为如下几步:1、把项目转化成JET项目要在项目中使用JET,必须首先把它转化成JET项目,可以通过Eclipse向导来转化成JET项目,这样会在项目的根目录下创建一个名字为templates的文件夹,而且给项目添加了一个JETBuilder,这个构建器会自动将templates文件夹下的模板文件进行编译,生成代码。2、设置JET在项目上右击,在弹出的快捷菜单中选择―属性‖命令,打开JETSettings选项卡,在这个选项卡中就可以修改模板文件夹和源文件夹了。注意此处必须输入源文件夹的名字,否则在生成代码的时候就有可能出现代码生成位置出错的问题。3、创建模板文件JET的模板文件的命名规定是在要生成的代码生成器类的文件名后加jet,比如想命名我们的代码生成器为MyJSF.jsp,那么只要把模板命名为MyJSF.jspjet就可以了。因此可在templates文件夹下创建一个文件,创建完毕之后,创建完模板文件以后,JET构建器就去尝试构建。代码生成器生成代码的方法是generate,因为我们经常需要传递一些参数给代码生成器,所以generate方法有一个类型为Object的参数,此参数在模板中可以用argument取得。此开发环境我们要使用JET生成两个文件,一个是JSP文件,一个是JAVA文件。分别使用JSFCodeGenerator.jspjet模板和EventCodeGenerator.javajet模板来创建。在生成JSP文件前,先遍历整个页面编辑器,对编辑器内的控件进行定位,判断控件间的关系,如包含、并列或上下,获取控件的所有信息,然后根据这些信息调用代码生成器,生成对应的JSF的代码。生成JAVA文件主要是在用户双击页面编辑器控件时产生的,此文件主要是便于用户对控件事件编程,此类实现了两个监听接口,一个事件监听,一个是值变监听。2)构建器构建器又叫增量式项目构建器,只要相关项目中的资源发生改变,构建器就会自动执行。比如,当创建或者修改Java源代码文件的时候,Java构建器就会构建这个Java源代码文件生成类文件。如果批处理这些修改的话,构建器将会收到包含所有发生变化的资源列表的唯一一条通知消息,而不是针对每一个变化的资源均收到一条通知消息。需要注意的就是构建器必须增量地执行,也就是只有那些发生改变的派生资源进行构建,如果每次改变一个资源都要对所有资源进行构建的话就会非常占用资源。Eclipse中的构建器一般从IncrementalProjectBuilder中派生,IncrementalProjectBuilder类中定义了一个抽象方法build,这个方法如下:64 5建立WEBRAD开发环境protectedIProject[]build(intkind,Mapargs,IProgressMonitormonitor)构建器必须被安装到具体的项目中才能发挥作用。最常见的为项目增加构建器的方式是自定义一个项目新建向导,在这个向导中为新建的项目增加构建器,但是这样做对于我们的界面设计工具来说就过于复杂了。为项目增加构建器其实只要修改项目的项目描述即可,因此我们准备为系统增加一个右键菜单项―添加UI构建器‖,当用户选择某个项目的时候这个菜单项就显示出来,用户单击这个菜单项就可以轻松地为已有的项目增加构建器。Eclipse中的菜单项一般都对应一个Action类,这里的菜单项就是AddBuilderAction,它实现了IObjectActionDelegate接口。可以看到代码的核心方法就是addUIBuilder,在addUIBuilder中首先从项目的项目描述中得到所有定义好的构建器,然后调用IProjectDescription的newCommand方法得到一个新的构建器,并把构建器设置为这个新构建器的Id,最后将设置后的构建器重新添加到项目描述中。需要特别注意的是这里设置的新构建器的Id的组成方式是―插件id‖+―.‖+―构建器id‖,也就是―com.cownew.uidesigner.UIBuilder‖,而非构建器的ID―UIBuilder‖,这一点是值得特别注意的。最后需要将AddBuilderAction添加到plugin.xml中去:②WEB部署的实现当WEB应用程序在WEB容器中运行时,才能真正实现WEB应用的B/S模式,为使前面所生成的代码能在Web容器中运行,故此快速应用开发框架开发环65 重庆大学硕士学位论文境也要实现WEB的部署,达到真正的WEB应用。本开发环境使用Tomcat插件来实现WEB容器,使开发环境依赖Tomcat插件,在RAD开发环境创建工程的时候,调用Tomcat插件创建工程的方法,在工程创建加入如下代码。//添加Tomcat工程特性TomcatProject.addTomcatNature(jproject);TomcatProjecttomcatPrj=TomcatProject.create(jproject);tomcatPrj.setWebPath(jproject.getElementName());tomcatPrj.setUpdateXml(true);tomcatPrj.setRootDir(―web‖);tomcatPrj.saveProperties();tomcatPrj.fullConfiguration();其中,jproject是一个Java工程,这样创建的工程就有Tomcat工程的特征,Tomcat插件会自动维护Eclipse中的Tomcat工程,并生成部署的配置文件。66 6WEBRAD应用实例6WEBRAD应用实例WEBRAD开发环境提供了可拖放的可视化控件,开发人员可以快速的定制自己的界面,通过事件机制编程可以快速的开发出WEB程序应用,下面就用本开发环境实现一个网上CD商店系统,为了简化系统的复杂性,本文主要对此系统的后台录入系统进行实例讲解,录入系统主要是针对后台网络管理员,方便管理员对CD资料和用户信息的管理。6.1具体实现①系统结构图此系统使用多层的整体架构,将该系统在逻辑上分为五层:客户层、表示层、业务层、持久层和数据库层。采用多层架构以后,客户层主要用于人机交互。表示层主要负责对客户请求作出响应,调用业务层组件,并将结果返回到客户层。业务层主要负责应用逻辑的实现,持久层负责存储从应用数据库的数据,也负责数据的检索、更新和删除。数据库层则主要负责数据的存储和组织、数据库的分布式管理、数据库的备份和同步等等。这样表示层可以不知道数据库的结构,它只要维护与业务层之间的接口即可,而业务层也只是和数据持久层的接口打交道。这种方式在一定程度上增加了数据库的安全性,同时也降低了对每一层开发人员的要求,表示层可以由精通图表设计的人员来做,业务层的开发人员只需专注于业务逻辑的理解,持久层人员则关心数据的相关操作,可以有更多的精力去优化数据库。具体如图6.1所示。业数表务据示逻持数据库层辑久层层图6.1系统多层结构图Figure6.1MultilayerofSystemStructure②网上CD商店录入系统的功能1)管理员能够查看、搜索CD资料。2)管理员能够录入CD光盘信息。67 重庆大学硕士学位论文3)管理员能够修改和删除CD光盘信息。4)管理员能够查看用户信息。5)管理员能够修改和删除用户信息。③数据表结构1)CD表。表名为CDInfo,表示CD光盘的基本信息。主表中的字段有CDId、名称、类别Id、专辑、艺术家和价格。2)分类表。表名为CDT,表示CD对应的分类,类别Id、类别名称6.2开发步骤6.2.1建立应用通过RADWEB框架开发环境的新建向导可以新建一个WEB项目,应用为Eclipse中的一个工程。在应用向导中输入项目名CDStore,以及相关的公司、作者等,在第二个页面定义对应的项目项目路径、源文件夹等。如图6.1所示。图6.2项目向导Figure6.2WizardoftheProject6.2.2持久化配置根据对数据的分析进行持久化配置,此系统使用了MySQL数据库,数据库名为demo,使用了两个表分别是cd和cdtype,把这两个表当成对象进行数据持久化配置。配置如图6.3所示。68 6WEBRAD应用实例图6.3Hibernate配置Figure6.3ConfigurationofHibernate6.2.3定制界面使用开发环境编辑页面进行页面绘制。如图6.4所示。图6.4定制界面Figure6.4DarwofUI69 重庆大学硕士学位论文6.2.4事件开发WEBRAD开发环境另一个特点是基于事件编程,开发人员可以根据需求对页面内的控件进行事件编程,如使用添加按钮事件时,则对添加按钮的图标双击进行按钮事件编程界面,同时自动生成与此按钮相关的实现接口框架,具体为AddButtonListener.java,此类实现了ActionListener接口,开发人员需重构processAction方法,此方法来实现事件要做的动作,一旦用户点击此按钮就会调用此方法。具体如图6.5所示。图6.5事件开发Figure6.5EventDevelopment6.2.5部署并运行WEB应用通过WEBRAD框架开发环境生成出来的代码,已经是一个比较完整的WEB应用。包括生成的数据表、WEB页面、服务器端处理类和、Hibernate框架的相关类。把生成的代码部署到Tomcat中,运行Tomcat,在浏览器地址栏输入―http://localhost:8080/cdstore/index.faces‖可看到WEB应用运行的效果图,如图7.6所示。70 6WEBRAD应用实例图6.5WEB应用效果Figure6.5EffectofWEBApplication6.3框架开发环境评价通过WEBRAD框架开发环境基本上可以实现WEB应用的开发,开发人员可以使用拖放控件定制界面,双击控件对控件进行事件编程,本实例使用了一个单界面的开发的例图,但在多界面的复杂情况下,由于界面上控件数据较多,可能会出刷新速度慢。下一步将进行这方面的改进,将界面上的控件进一步的管理,对那些不操作后台数据的事件,可以通过表示层直接对界面上的控件进行更新,也就是使用丰富互联网应用程序(RichInternetApplication简称RIA)技术,常用的是Ajax异步刷新机制;再一个开发环境对数据库的展示还是由开发人员编程实现,由于WEB应用大多涉及数据库的操作,应当将数据库的表示层进一步提升,通过数据表控制来定制后台数据库的显示,这也是进一步研究的内容。表6.1是WEBRAD框架开发环境与其它相关框架比较的表格,需要说明的是本框架开发环境是与标准的Struts、JSF等这样的框架进行比较,可以看出此开发环境支持拖放编程和事件机制,同时不需要页面跳转,另外开发环境又增加了自动部署和数据持久的附加功能,为快速开发进一步提供帮助。71 重庆大学硕士学位论文表6.1WEBRAD和其它框架比较Table6.1compareWEBRADframeworkwithotherframeworks拖放编程事件机制页面跳转自动部署数据持久WEBRAD支持支持不需要支持支持Struts不支持不支持需要不支持不支持JSF不支持支持需要不支持不支持Ajax不支持不支持不需要不支持不支持72 7结论与展望7结论与展望7.1研究的成果本文通过学习和研究事件驱动机制,快速应用开发的应用原理以及WEB应用开发下的特殊机制,设计并实现了WEBRAD框架开发环境。通过此开发环境开发人员能所见即所得的拖放控件,便捷的事件编程,快速的配置、部署相关文件来快速的开发WEB应用程序。此开发环境实现了在B/S模式下如C/S模式下事件编程的方便性,开发人员可以体验到像在VB上编程的快乐,由于B/S模式下请求响应的无状态性,故对请求响应的过程进行封装,使用一个专用的Servlet统一管理响应事件处理,并将页面上的诸如按钮、文本框之类的控件用控件树来控制,每一个控件都有它的生命周期,并对这些控件的事件或值变进行监听,如发生事件触发则执行相应的事件操作,同时根据需求对控件进行更新,这样WEB下的请求响应就转变为有状态的事件驱动。开发人员不用再考虑那些繁琐的页面跳转,所有的页面只在当前的页面上显示,只是控件数量不同或控件的位置变化,这样开发人员可以将更多的精力投入到业务逻辑上,从而提高开发效率。7.2需进一步完善的问题本研究虽然取得了一些成果,但由于时间和精力有限,本研究还存在一些不足,有一些技术问题还未实现,今后有时间会继续从事这方面的研究,对此框架开发环境进行不断的改进和提高。这些需完善的主要表现在:①开发环境页面编辑器的控件定位是使用相对位置来判定的,JSF代码也是根据此来自动生成,因此在实现那些特别复杂的或个性的页面上代码自动生成还有困难。下一步将使用精确的定位方式如CSS等技术来实现控件定位,并提供一些设计模版和自定义的模版以方便开发人员使用。②开发环境在实现页面编程方向没有实现异步通讯的机制,以快速访问数据库,提高用户使用体验。下一步将引入AJAX技术,使开发环境支持快速的AJAX技术开发,提供AJAX控件和相应的JavaScript开发环境及编程提示,为开发人员提供异步通讯编程机制。③开发环境在控件数量方面还不够丰富。控件数量的多少直接影响开发项目的生命周期,因此足量的有用的控件是非常必要的。下一步将对常用页面分析提炼出更多有用的控件加入控件选项板,同时为开发人员提供一种可以自定义控件的配置方法控件也是很有必要的。④开发环境的细节部分还需要逐步完善。如没有提供WEB开发的国标化、控73 重庆大学硕士学位论文件的有效性验证、界面的友好性、兼容其它框架能力等。下一步是对开发环境的细节部分进行查漏补缺,逐步完善框架开发环境的各种功能,增强对其他框架的整合能力。7.3展望当前的WEB开发框架琳琅满目,但从发展的趋势可以看出,是向着快速应用开发的模式方向发展,可视化的编程环境,事件的编程机制,代码的自动生成,项目的总体部署与配置等,大大的提高软件的重用性,有效的减短开发周期。另外,众多的调查机构研究表明,代表开源的可扩展的插件机制的Eclipse平台受到开发人员的热烈欢迎,事实上,这也下符合人类在现实世界的追求,开源意味着自由开放,可扩展的插件机制意味着可持续地发展。因此,未来的框架开发环境,也应当具备这些特点:RAD,快速应用开发已深入人心,以其特有的开发模式为人们所吸引,开发周期短,灵活性强,简单的拖放可重用控件,基于事件的编程,就可完成程序框架应用;开源,可以让其他人员了解自己的程序,指出程序的不足,修正程序的BUG,获得广大开发人员鼎力支持的框架工具才会更完美,功能才会更完善;可扩展的插件机制,能充分调动开发人员的主观能动性和积极性,能使开发人员开发出各种各样的插件,从而才能让已有框架工具的功能不断地得到充实和增加,才能让开发框架工具不断向前发展。74 致谢致谢本文的研究工作是在我的导师邢永康副教授的精心指导和悉心关怀下完成的,在我的学业和论文的研究工作中无不倾注着导师辛勤的汗水和心血。导师的严谨治学态度、渊博的知识、无私的奉献精神使我深受启迪。从尊敬的导师身上,我不仅学到了扎实、宽广的专业知识,也学到了做人的道理。在此我要向我的导师致以最衷心的感谢和深深的敬意。感谢实验室的所有同学,感谢他们对我的关心和帮助,与他们在工作和生活方面的讨论使我受益非浅,让我度过了三年快乐而充实的时光。同时我还要感谢我的父母及家人,他们一直默默地支持着我,是他们给了我克服困难的勇气和积极进取的热情,在此,我祝福他们永远健康快乐!在此,向所有关心和帮助过我的领导、老师、同学和朋友表示由衷的谢意!最后,衷心地感谢在百忙之中评阅论文和参加答辩的各位专家、教授!秦长春二OO八年四月于重庆75 重庆大学硕士学位论文76 参考文献参考文献[1]GaneC.RapidSystemDevelopment[J].Prentice-Hall,1989,1:12.[2]Boehm,B.MakingRADworkforyourproject[J].ComputerVolume32,Issue3,March1999,Page(s):113-114,117.[3]MitchellD,Lubars.ReusingDesignsforRapidApplicationDevelopment[J].MicroelectronicsandComputerTechnologyCorp,IEEE,1991.[4]KeithRapley.RADorTRADorBoth?[J].TheFutureofSoftwareDevelopment,IEEE,1995.[5]GrandyBooch,JamesRumbaugh,IvarJacbson著.统一软件开发过程[M].周伯生等译.北京:机械工业出版社,2002.[6]徐长盛,戴超,谢立.一种快速开发Web应用程序方法的研究[J],计算机工程与设计,2004,(12).[7]Venkitachalam,G.;Tzi-ckerChiueh.HighperformanceCommonGatewayInterfaceinvocation[J].InternetApplications,IEEEWorkshopon26-27July1999,Page(s):4–11.[8]P.Bernstein.Middleware:AModelforDistributedSystemServices[J].CommunicationsoftheACM,39(2):86-98,Jul1996.[9]BruceEckel.Java编程思想第二版[M].侯捷译,北京:机械工业出版社,2002.594-788.[10]丁峰,李涓子,王克宏.Web应用未来之路[J].计算机教育,2004,(04).[11]BarryBoehem.MakingRADWorkforyourProject[J].UniversityofSouthenCalifornia,IEEE,2001.[12]Mills,S.A.;Karins,J.P.;Dydyk,R.B.Patternrecognitionprototypingtool[J].ImageProcessing,Proceedings.,InternationalConference,26-29Oct.1997Page(s):312-315vol.3.[13]文武.RAD-编程的终结?[J].中国计算机用户,1995,12.[14]ABirell,BNelson.Implementingremoteprocedurecalls[J].ACMTransactionsonComputerSystems,2(l),Feb.1984.[15]潘勇.基于组件技术开发的重要实现途径一一RAD的思考[J].电脑开发与应用,2007,20:7.[16]R.E.Johnson,B.Foote.DesigningReusableClasses[J].JournalofObject-OrientedProgramming,1(2):22-35,June/July1988.[17]YaodaLiu;Schwefel,H.-P.Anenhancedoptimizedlinkstateroutingwithdelayedeventdrivenlinkstateupdating[J].Personal,IndoorandMobileRadioCommunications,IEEE16thInternationalSymposium,11-14Sept.2005Page(s):1409-1413Vol.2.[18]ChafleG.,DasG,DasguptaK.,KumarA,MittalS,MukherjeaS,SrivastavaB.AnIntegrated77 重庆大学硕士学位论文DevelopmentEnvironmentforWebServiceComposition[J].WebServices,IEEEInternationalConferenceon9-13,July2007Page(s):839–847.[19]Barnett,A.J.Client/servercommunicationsfutures[J].Client/ServerComputing.SeminarProceedings(IEEDigestNo.1995/184),InternationalSeminar,30-31Oct.1995Page(s):17/1-17/8vol.1.[20]ZhenyuCai,ShudongWang;XiaozhanPeng;BaozhengChen.RemotesensingimageinformationissuebasedonC-SandB-S[J].GeoscienceandRemoteSensingSymposium.Proceedings.2005IEEEInternationalVolume2,25-29July2005Page(s):4pp.[21]NikhilKothari,UandanaDatye.ASPNET服务器控件与组件开发[M].邓春红,王琳,傅蓉等,北京:机械工业出版社,2003,[12].[22]AlexBerson,McGraw-Hill.Client/ServerArchitecture[J].NewYork:ComputerCommunications,IEEE,1992.[23]QinLi,HuibiaoZhu,JifengHe.AnInconsistencyFreeFormalizationofB/SArchitecture[J].SoftwareEngineeringWorkshop,31stIEEEMarch62007-Feb.82007Page(s):75–88.[24]MartyHall著,钟鸣,石永平译.Servlet与JSP权威指南[M].北京:机械土业出版社,2002,10-11.[25](美)梅特斯克,韦克著,龚波,赵彩琳,陈蓓译.Java设计模式[M].北京:人民邮电出版社,2007,51-73.[26]吴江,马瑞芳.事件驱动的B/S系统开发框架Echo研究[J].微电子学与计算机,2004,2(21):10-14.[27]KumarHarikumar,ALeeR.;Chia-ChuChiang;Hae-SoolYang.AneventdrivenarchitectureforapplicationintegrationusingWebservices[J].IEEE2005.[28]Harikumar,A.K.;Lee,R.;HaeSoolYang;Haeng-KonKim;ByeongdoKang.Amodelforapplicationintegrationusingwebservices.[J].IEEE2005.[29]童立,马远良.设计模式在基于组件的框架设计中的应用[J].计算机工程与应用,2002,(17).[30]陆荣幸,郁洲,阮永良,王志强.J2EE平台上MVC设计模式的研究与实现[J].计算机应用研究,2003,(3).[31]EricClayberg,DanRubel.Eclipse:BuildingCommercial-QualityPlug-ins,SecondEdition[M].AddisonWesleyProfessionalMarch22,2006.[32]甘树满.基于Eclipse的开源框架技术与实战[M].北京:电子工业出版社,2007.[33]BillMooreetal.EclipseDevelopmentusingtheGraphicalEditingFrameworkandtheEclipseModelingFramework[M].IBMRedbooks.2004.78 参考文献[34]BillDudeney,JonathanLehr,BillWillis,LeRoyMattingly.MasteringJavaServerFaces[M].WileyPublishing,Inc.,Indianapolis,Indiana,2004.[35]BudiKurniawan.JavaServerFacesProgramming[M].TheMcGraw-HillCompanyes,Inc,2004.[36]HansBergsten著.JavaServerFaces交互式网站界面设计[M].南京:东南大学出版社,2006.[37]陈天河.Hibernate项目开发宝典[M].北京:电子工业出版社,2006.[38]周竞涛,赵寒,王明微等.Eclipse完全手册[M].北京:电子工业出版社,2006.79 重庆大学硕士学位论文80 附录附录作者在攻读硕士学位期间发表的论文目录:[1]秦长春,邢永康.JSF整合AJAX框架设计方案的研究.微处理机.已录用(拟2009年5期发表.).81 重庆大学硕士学位论文82

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。
关闭