| 作者:刘睿 |
|
把AJAX引入Java应用程序,有它的优势和不足。如何解决AJAX的异步通信模型与传统J2EE内置的同步模型融合,成为有效利用AJAX的关键。 在Web 2.0的热潮中,越来越多的的开始关注AJAX。虽然它只是几项已有技术的组合,但是它打破了使用页面重载技术的常规组合,可以说AJAX已经成为Web开发的重要工具。众多的社区也对AJAX投入了极大的关注,如何解决J2EE架构的同步通信模式与AJAX的异步通信模式成为了Java业界的焦点。 AJAX技术通过消除过多的Web页面刷新,提高了应用程序的可用性。而且AJAX二者通吃的技术,同时利用了客户端和服务器端代码,向Web用户呈现了几乎无缝的用户界面。本文通过J2EE应用程序的设计、开发、执行和测试各阶段引入AJAX会带来的影响对采纳AJAX基于异步通信的模式会存在的问题保持清醒,有助于踏上有效集成AJAX的正确道路,更有效而顺利地利用AJAX。
解决设计缺陷 相当一段时间以来,Java社区一直在努力把好的设计模式应用到与Web有关的应用程序开发上。其中使用最广泛的一个模式就是模型-视图-控制器(MVC)。一些开放源码架构,例如Apache Struts,就基于这个设计模式。 MVC具有问题隔离和减少冗余代码的优势。问题隔离在整个应用程序架构中使用预先协商好的接口,从而让应用程序开发项目中的每个开发人员都专注于自己特定的角色。例如,模型层的开发人员侧重于JDBC、EJB组件或者与底层数据持久技术接口的Java类这一类的技术。视图层开发人员侧重于JSP、标记库和其他与表示有关的技术。控制器层隔离及协调模型和视图,把进入的请求路由到后端持久性调用,同时维护问题的清晰隔离。 把AJAX引入J2EE Web应用程序对于问题的隔离以及开发人员角色的隔离是有影响的。在某些情况下,AJAX会把大量JavaScript代码带回视图层(JSP)页面。 从表1与表2(下页)的对比中不难看出,由于使用了AJAX,视图层的脚本编写量增加了,从而导致三个明显缺陷:JSP要求大量的JavaScript代码,设计破坏了角色问题的隔离,设计重新带回了单一JSP。 那么面对这些设计缺陷,我们又该何去何从呢? 设计时脑子里记着重用 编写特定于AJAX支持的代码通常很难避免,只能优化脚本代码,以便能够最大限度地重用它。 采用客户端MVC方法 可以合并使用客户端MVC方法,这种方法可以促进问题的隔离,但是增加了复杂性,所以使用的时候要仔细考虑利弊得失。 重新评估设计的正确性 实际上,AJAX为Web应用程序提供了桌面应用程序的属性。如果一个Web应用程序中大多数客户端交互都利用AJAX,那么这个应用程序可能最好设计成桌面应用程序。
处理开发困境 在J2EE架构中使用AJAX时,重要的是完整理解同步和异步通信模型的区别。对异步通信模型支持的缺乏,会对客户端开发、与Web架构的集成、标记库的使用以及线程的行为有影响。 在同步请求/响应通信模型中,总是浏览器发起请求(通过Web用户)。接着,Web服务器、应用服务器或Web应用程序响应进入的请求。在处理同步请求/响应对期间,用户不能继续使用浏览器。 在异步请求/响应通信模型中,浏览器通过Web用户到Web服务器、应用服务器或Web应用程序的通信(以及反过来)是松耦合的。在异步请求/响应对的处理中,Web用户在当前异步请求被处理时还可以继续使用浏览器。一旦异步请求处理完成,异步响应就回客户机页面。多数情况下,在这个过程中,调用对Web用户没有影响,他们不需要等候响应。 客户端开发 在向Web应用程序引入AJAX时,开发团队需要注意几个风险,主要与生成的HTML页面及其与浏览器的交互方式有关。 可能没打开脚本功能,出于各种原因,在许多用户的浏览器上禁止了JavaScript支持。 跨浏览器支持增加了代码需求,支持多种浏览器和多个浏览器版本的应用程序,要求的脚本代码可能会增多,因为浏览器解释DOM对象的方式有细微的差异(所以操作这些元素的JavaScript代码也有差异)。 JavaScript不安全,在多数浏览器中,可以选择查看源代码选项,查看到与 HTML页面关联的JavaScript源代码。在使用AJAX模式时,要确保脚本代码中实现的逻辑不是敏感逻辑。 与Web架构集成 试着把AJAX开发与所选的J2EE Web架构集成,是很自然的。但是只有少数的J2EE架构对异步通信模型提供直接可以使用的支持。异步序列恰恰是多数 J2EE架构所不支持的,从而造成与AJAX的集成非常困难。 那么如何克服这个问题呢?有如下几个办法: 与Web架构并存,不必等待内置的AJAX支持或者在所选的架构中强行实现 AJAX支持,可以使用独立的servlet来处理全部异步请求。DWR就使用了这种方式。这种方式的不足在于AJAX请求不能方便地利用架构的特性。 与Web架构集成,通过使用免费的扩展或编写定制的扩展,可以设计出与所选Web架构集成的途径。 迁移到支持AJAX的架构 ,更新的架构开始支持异步通信模型。Apache Shale是其中比较优秀的一个。 使用标记库 大量使用标记库(taglib)在Java的 Web应用程序开发中是很普遍的。像许多 J2EE架构一样,有些标记库现在也不支持异步通信模型,没有把通过 XMLHttpRequest提交的数据转换成 HttpServletRequest的途径。实际上,不支持异步通信的标记库,在AJAX XMLHttpRequest调用期间不工作。放弃使用不支持异步模型的标记库,把现在由标记库生成的代码迁移到HTML/JavaScript代码。使用已经解决了这个问题的AJAX架构(例如DWR)或者使用支持异步模型的标记库(例如AJAXTags)。 线程问题 在典型的同步Web应用程序中,有些领域对按钮或链接点击要求更长一点的处理时间。没有耐心和没经验的Web用户通常会不止一次地点击按钮或链接,以为可以帮助加快处理速度,从而引发多重表单提交。其他时候,用户认为需要双击。Web应用程序中的多重表单提交在某些情况下是无害的。而在其他情况下,副作用可能造成严重的线程问题或争用情况。例如,在银行应用程序中多次点击转帐按钮,可能造成不希望的多次转帐。 既支持同步通信模型又支持异步通信模型的Web应用程序会发现,如果它的功能没有正确分析和规划,那么自己就处在了相似的困境中。支持两种通信模型的应用程序在某个页面上可能混合了服务器端调用。就像在多重点击场景中一样,异步调用可能处理得慢些。如果应用程序不做预防,用户可能会在异步线程正在处理时又调用了一个同步调用,因为页面没有刷新,所以无法阻止页面上的进一步活动。结果是两个线程并发处理。虽然不是由Web页面上的同一按钮或链接引发,这类情况还是会造成服务器端的线程问题(与多重点击问题类似)。 一般来说,有两种方式可以避免这类情况发生。 客户端解决方案 一旦点击了一个链接或按钮,就用JavaScript确保禁止后续的页面提交,直到当前线程执行完成。 允许多线程提交 但是依赖于服务器端代码中的同步来避免争用情况。如果引入同步来解决这个问题,请记住J2EE Web 组件(servlet、portlet、JSF等)是多线程的。要当心大段代码的同步,特别是与请求/响应生命周期处理有关的代码。在效果上,同步的误用,会把应用程序变成单线程应用程序,从而降低吞吐率。
克服性能缺陷 使用AJAX还有可能影响基于J2EE Web的应用程序的性能。允许每个请求上有额外线程的可能性,可能会影响两个资源。 首先,servlet容器的线程池可能受到影响。线程池指定Web容器中允许并发运行的线程的最大数量。每个客户机请求需要一个线程。但是,一个客户机请求不一定等于一个用户请求。浏览器可能为一个用户请求要求多个客户机请求。例如,提交表单的一个用户可能要求多个客户机请求(其中包含提交表单的值、检索GIF文件、检索JavaScript文件、检索CSS文件)。如果允许并发地提交同步和异步请求,就意味着每个用户请求至少要支持多出一个的线程消耗(用于AJAX请求)。虽然为每个用户请求多增加一个线程的可能性看起来不多,但是当应用程序处在负载之下时,影响就明显了(这时每个用户请求多出的一个额外线程乘上平均用户数量)。很明显,这种情况有可能影响servlet容器的性能。 另一个可能受影响的资源是数据库连接池。典型的J2EE应用程序支持一个用户请求的两类序列:浅(shallow)请求深(deep)请求。浅请求是执行服务器端代码但是不访问持久性存储(例如数据库)就完成请求的Web页面发出的请求。 深请求是执行服务器端代码并访问持久性存储才能完成请求的Web页面发出的请求。在深请求序列中,数据库连接池的这些方面可能会由于允许多个线程而受到影响:等待连接的线程的平均数量,以毫秒为单位的连接的平均等候时间,连接被使用的平均时间,可能需要提高连接池的平均大小或连接数量。 Java开发人员一直在不断地努力为J2SE和J2EE代码提供单元测试工具。由于AJAX的引入造成浏览器内的JavaScript增多,对可靠的JavaScript单元测试架构也提出了要求。现在可用的架构有JsUnit、Selenium和HttpUni。 这些架构提供了为JavaScript函数开发单元测试的工具,可以操纵Web页面上的DOM元素。它们允许把单元测试组织成测试套件。 Selenium的浏览器兼容性测试特性允许在不同的浏览器和操作系统上测试 JavaScript 函数。它利用 JavaScript 和Iframe在浏览器中嵌入了测试自动引擎。这项技术应当可以在任何支持 JavaScript的浏览器中工作,对于支持多个浏览器和浏览器版本的应用程序来说特别有用。Selenium和JsUnit都支持持续集成,可以把JavaScript单元测试和测试套件集成到自动构建过程。 把AJAX引入Java应用程序,也有它的优势和不足。为了避免盲目,请确保在采用AJAX之前对潜在的问题领域有全面的事前规划。
MVC模式
链 接 几个好用的AJAX工具 Bindows Bindows是一个通过DHTML、JavaScript、CSS和HTML等技术强劲联合起来的一套完整的Windows桌面式的Web应用程序解决方案。 Bindows无需下载安装客户端支撑组件(如Java、ActiveX或Flash),仅需一个浏览器。纯OO的理念体现在Bindows任何地方,Bindows或许是笔者见过的最完整最强大的AJAX应用程序平台。 DOJO DOJO提供完整的轻量级窗口组件和浏览器-服务器消息映射支持,预置了很多模块,可以实现完整的轻量级窗口组件及很多功能。DOJO的包加载机制(Package System)可以实现动态加载所需模块,而且用户可以编写自己的DOJO扩展模块,有很好的灵活性。
SAJAX SAJAX的名气不小,很多人都听过甚至用过,不过缺点就是它的这套映射理论感觉较繁锁,远不如一些轻量级的封装库好用,不过SAJAX最大的特点就是支持的平台丰富,几乎囊括了Web下所有常用的编程语言和平台
Google Web Toolkit(GWT) GWT可以让java程序员不需要写任何HTML和JS就可以轻松地构建一个AJAX应用程序。这个工具包可以把你的java转换成浏览器上的js和html。当然,如果你觉得GWT不能构建出你所需要的客户端脚本,你也可以通过JSNI来自己写JS代码。 |