级别: 中级 Daniel Wintschel ([email protected]), 撰稿人和开发人员, 自由职业
2007 年 11 月 22 日
在 Web 2.0 时代,开发人员和用户都对基于 Web 的应用程序的可用性和响应性抱有很高的期望。除非是在过去的两年内一直没有关注过这个领域,否则一定听说过 Asynchronous JavaScript + XML(Ajax 技术)。通过 Ajax,可以构建灵活、响应性好和高度动态的基于浏览器的用户界面,而且根本不需要进行浏览器页面重载。本文将介绍一种 Java™/JavaScript 库 —— AjaxTags,它让您可以很轻松地将 Ajax 功能集成到 JSP 页面中。
简介 以前,基于 Web 的用户界面(包括页面和应用程序)要求用户所做的每个请求都强制执行一次页面刷新,这消耗了大量的时间和带宽。重复的页面刷新的后果是 Web 体验变得异常缓慢和沉闷,即使对于那些具有高速的宽带连接的用户也是如此。
|
developerWorks Ajax 资源中心 查阅 Ajax 资源中心,这里几乎囊括了关于 Ajax 编程模型的所有信息,包括各种文章和教程、论坛、博客、wiki、活动和新闻。 |
|
现 在,各地的开发人员都在寻找新的技术和技巧,以便显著提高基于 Web 的应用程序的性能和用户体验。用 Ajax 编写的 Web 应用程序允许数据在后台被异步地发送给服务器,而同时又能在不重载页面的情况下更新此 Web 页面的各个部分。Ajax 涉及到很多对象和技术。尽管缩写词 Ajax 中有字母 X,但 XML 可能永远都不会用到。从浏览器发回的响应也可以是多种格式或类型中的一种,包括纯文本、HTML 或 XML 等。 本文描述了一个小型紧凑的 JSP 标记库,即 AjaxTags,该库使用某些外部 JavaScript 来为 JSP 页面提供易用的 Ajax 支持。
立即开始 若想跟随本文进行学习并运行本文中所描述的这些示例,就需要选择使用几个工具。本文所使用的每个应用程序都是免费和开源的。
|
将 Ajax 功能构建到应用程序中在很多方面都会对用户有利,而且通常会减小开发的复杂性。AjaxTags 和其他经良好测试的 JavaScript 库可以为您完成大部分编程工作。 |
|
运行本文给出的示例所使用的参考实现 servlet 容器是 Apache Tomcat。它可以从 Apache Tomcat 网站(请参见 参考资料)免费下载。本文中的示例使用的是本文写作时的最新版本,为 6.0.13。 此外,还需要登录到 SourceForge 下载 AjaxTags 示例应用程序(有关链接,请参见 参考资料)。 这里的示例使用的是 Ajax Tags 演示下载的 1.3 版。这是一个标准的 WAR 文件,可以将其部署到 Tomcat webapps 目录。如果不想让要浏览的 URL 太过冗长,在部署它之前,可以对此 WAR 文件进行重命名。否则,需要浏览到:http://localhost:8080/ajaxtags-1.3-beta-rc6-1/。 现在让我们立即开始吧。
Ajax 是否是为了清洁之用? 还 只是几年之前,即使是顽固的开发人员也会将 Ajax 与由 Colgate-Palmolive 开发和生产的那个流行清洁剂联系在一起,而不是将其视为一种可以提高在线体验的 Web 开发技巧。现在,Ajax 技术越来越受欢迎,大家不禁都想要获得有关其工作原理以及在何种情况下可以使用它的全部信息。 工作原理 在开发和编写 Ajax 应用程序时,需要理解前台和后台的工作原理。如下所示的是应用程序内的一种典型的事件流:
- 用户请求一个网页。
- 用户更改此网页上的状态(例如,单击一个链接、从选择框中进行选择、单击了某个单选按钮或复选框)。
- 状态的改变会击发事件,调用一个 JavaScript 函数。
- JavaScript 函数实例化一个
XmlHttpRequest 对象,该对象会在后台异步地产生一个对服务器的 HTTP 请求(注意,没有发生页面刷新)。
- 服务器响应,向 JavaScript 函数返回所请求的数据。
- JavaScript 函数通过使用额外的 JavaScript 和/或 DHTML 更新和修改所正在查看的页面。
负 责更新当前网页的某些部分的 JavaScript 需要知道哪个 HTML 元素负责更新。要实际动态更新给定页面内的特定元素(在无需重载此页面的情况下),需要分配给这些 HTML 元素一个惟一 ID。清单 1 所示的是此演示中的一个简单的例子,稍后我们将对其进行更深入的分析: 清单 1. 为 HTML 元素分配 ID
<select id="model" disabled="disabled"> <option value="">Select model</option> </select>
|
清单 1 为这个特定的选择框分配的 ID 为 model。通过这个 ID,就可以利用 JavaScript 轻松定位和处理所选元素及其内容。 AjaxTags API 使用的是某些很好的、开源的第三方 JavaScript 库,这些库会为您完成几乎全部的繁重编程工作。其中的一个好处是这些库均包括丰富的特性并经诸多浏览器广泛测试,所以尽可放心使用。AjaxTags 所使用的第三方库包括:
- Prototype(一种带多种实用函数的 JavaScript 库)
- Script.aculo.us(一种带多种可视效果的 JavaScript 库)
- Overlibmws(一种 DHTML 弹出库)
何时使用 AjaxTags 在很多典型的环境中都可以使用 AjaxTags,这样一来,不仅可以方便开发人员,而且还可以提高应用程序的用户体验。其中的一些用例包括:
- 基于第一个下拉框中所做的选择来修改第二个下拉框的内容
- 基于单击或鼠标悬浮事件从服务器发起对额外信息的请求,而且无需刷新用户所查看的页面
- 基于用户输入的数据在服务器上执行计算,无需重载整个页面
让我们先来看一些如何将这些特性集成到应用程序中的实际例子。
将 AjaxTags 集成到应用程序 要将 AjaxTags 集成到应用程序中,必须满足几个先决条件。本节将会涵盖这些先决条件和依赖项。 依赖项 在下载和使用 AjaxTags 时最好的做法是下载整个二进制发布,而不仅仅是这个 JAR 文件。这样一来,您就可以获得随之捆绑的所有所需的依赖项,包括 Prototype、Script.aculo.us 和 overlibmws 库。 设置和配置 为了在应用程序中使用而对 AjaxTags 进行的设置和配置十分直观:
- 将 ajaxtags.jar 文件放入 WEB-INF/lib 目录。
- 如果使用的是较早版本的 servlet 容器(Servlet 2.4 / JSP 2.0 之前的版本),那么就需要向 web.xml 文件添加标记库定义;如果使用的是较新版本的容器,则无需这么做。
清单 2. 针对较早版本的 servlet 容器的标记库定义(添加到 web.xml)
<taglib> <uri>http://ajaxtags.org/tags/ajax</uri> <location>/WEB-INF/ajaxtags.tld</location> </taglib>
|
- 将依赖项 JavaScript 文件添加到 Web 应用程序。根据 AjaxTags 文档,需要如下内容:
- Prototype 1.4.0:prototype-1.4.0.js
- Scriptaculous 1.5.1:scriptaculous.js、builder.js、controls.js、dragdrop.js、effects.js 和 slider.js
- OverLIBMWS(可选,只用于 ajax:callout):overlibmws.js
一旦完成了这些主要步骤,就应该可以开始在应用程序中使用 AjaxTags JSP 标记库。从开发的角度出发,所必需的是 JSP 页面(视图)以及服务器端的数据处理程序,此处理程序能将合适的内容返回给由客户机收到的异步调用。 默认地,AjaxTags 可以处理 XML、HTML 和纯文本内容,这应该可以满足大多数的用户需求。API 本身包含一些辅助类以便用很少的几行代码就可以构建合适的响应。
AjaxTags 演示和示例 从 SourceForge 下载的 AjaxTags 演示应用程序包含很多实际例子。让我们先来看看其中的几个例子,这些例子向您展示了如何轻松地将类似特性集成到您自己的应用程序中。 注意:您所参考的这些示例使用的是硬编码的数据源。在实际操作中,您可以从数据库提取数据,而不是像这样使用硬编码到 Java 文件中的数据。 选择框更新、视图和 HTML 让 我们从客户端开始,在其中您可以亲历整个过程是如何从头至尾工作的。首先要看的是一个演示 JSP 的片段,其中包含了两个下拉框。此页面相关部分也与之类似(可以通过浏览到在 Tomcat 实例中运行的 AjaxTag 演示应用程序并单击 Select/Dropdown 示例中的 Run 来查看)。这个例子很好,原因是它利用了pre- 和 post-JavaScript 函数,及进度指示器。此外,一旦做出了合适的选择后,它还会展示汽车制造商的徽标(请参见 图 1)。 图 1. 下拉示例页面 正如您所见,有两个下拉框。让我们来看看实现上述功能的相关 JSP 编码(可以在 dropdown.jsp 中找到)(参见清单 3): 清单 3. dropdown.jsp 中的 HTML 选择框
<label for="make">Make:</label> <select id="make"> <option value="">Select make</option> <option value="Ford">Ford</option> <option value="Honda">Honda</option> <option value="Mazda">Mazda</option> </select> <span id="progressMsg" style="display:none;"> <img alt="Indicator" src="<%=request.getContextPath()%> /img/indicator.gif" /> Loading...</span> <label for="model">Model:</label> <select id="model" disabled="disabled"> <option value="">Select model</option> </select>
|
请注意那些为选定元素所指定的 ID,此外,第二个下拉列表中没有任何汽车模型而且还是禁用的。 选择框更新并进一步查看 JSP 标记语法 现在,让我们来看看这个应用程序为您完成所有任务的那些内容:AjaxTags JSP 标记库的实际使用。清单 4 取自同一个文件(dropdown.jsp): 清单 4. AjaxTag JSP 标记库示例:ajax:select 标记
<ajax:select baseUrl="${contextPath}/dropdown.view" source="make" target="model" parameters="make={make}" preFunction="initProgress" emptyOptionName="Select model" postFunction="resetProgress" errorFunction="reportError" />
|
在仔细研读清单 4 中的大块代码之前,请注意这段代码:${contextPath} 。要消除混淆,需要指出这实际是一个使用 EL(表达式语言)进行的变量设置,在 header.jsp 中定义,如清单 5 所示: 清单 5. header.jsp 中的 contextPath 变量定义
<c:set var="contextPath" scope="request"> ${pageContext.request.contextPath}</c:set>
|
我着重提到它,是为了让您能够清楚地看到 ${contextPath} 变量是如何被解析的。如果用 Java 编写,则其值会是 pageContext.getRequest().getContextPath() 的对等物。基于我的配置,${contextPath} 变量将是 http://localhost:8080/ajaxtags-1.3-beta-rc6-1 的值。 现在,再回到 清单 4,注意到为了向服务器进行异步回调,您必须要知道这个请求的 URL。AjaxTag 需要这个 baseUrl 参数,它是 ID 为 make 的选择框发生更改事件时所需异步请求的那个 URL。 知道了 ${contextPath} 的值后,就可以看到将要请求的 baseUrl 为 http://localhost:8080/ajaxtags-1.3-beta-rc6-1/dropdown.view。 baseUrl 后面还有 source 和 target 。这些参数代表了所处理的 HTML 元素的 ID。在本例中,处理了两个选择框:一个包含汽车制造商,另一个包含汽车模型。包含汽车制造商的选择框是源,包含汽车模型的选择框则是目标。 parameters 参数(请参见 清单 6)表示的是应该传递到被请求 URL 的一些额外参数: 清单 6. parameters 参数
请注意花括号内的语法为 make={make} 。 这就表明要将 make 的参数键追加到这个正被异步请求的 URL,而且作为数值,传递在相应的指定 HTML 元素中找到的值(基于 ID)。所以在这个示例中,后台的 JavaScript 将会用 make 的 ID 来获得这个 HTML 元素、获得该元素的值并将其作为 HTTP 请求的一部分传递。这听起来比实际的情况更容易让人混淆,所以让我们来看看最后的这个 URL,此 URL 在选择第一个选择框的内容时被请求(请参见 清单 7): 清单 7. 当用户从第一个选择框中选择 “Mazda” 时,所请求的 URL
http://localhost:8080/ajaxtags-1.3-beta-rc6-1/dropdown.view?make=Mazda
|
可以看到已经有一个参数被添加在 URL 的末尾,参数键是 make,而参数的值为 Mazda。 ajax:select 参数 preFunction 、postFunction 和 errorFunction 是所编写的定制 JavaScript 函数的名称,这些函数在时间或条件合适时调用。在本例中,命名的方式很明显。preFunction 在 Ajax 请求之前执行;postFunction 在 Ajax 请求完成且收到响应之后执行,errorFunction 在出现问题(比如请求返回了 500 内部服务器错误或资源不存在消息等等)时执行。 最后一个参数 emptyOptionName 是选项的值,这个选项显示没有做出某个选择。在本例中,恢复默认状态。 在使用浏览器请求此 JSP 页面之后,会注意到 ajax:select 标记已经由清单 8 所示的 JavaScript 片段所取代,此段代码嵌入在客户端的页面内(通过在 Web 浏览器中查看页面的源代码可以检索到): 清单 8. ajax:select 标记生成的 JavaScript
<script type="text/javascript"> new AjaxJspTag.Select( "/ajaxtags-1.3-beta-rc6-1/dropdown.view", { parameters: "make={make}", postFunction: resetProgress, target: "model", preFunction: initProgress, source: "make", emptyOptionName: "Select model", errorFunction: reportError }); </script>
|
通常,在浏览器计算这个 JavaScript 片段时,它才会执行。JavaScript 对象(AjaxJspTag.Select )被实例化,适当的侦听程序会被附加到合适的元素。 让我们浏览一下实际响应,该响应在 URL 寻找 make 为 Mazda 的汽车时在后台发送给浏览器,如 清单 9 所示(此响应是在 清单 7 中请求 URL 的结果)。 清单 9. Ajax 响应
<ajax-response> <response> <item> <name>Mazda 3</name> <value>Mazda 3</value> <value>false</value> </item> <item> <name>Mazda 6</name> <value>Mazda 6</value> <value>false</value> </item> <item> <name>RX-8</name> <value>RX-8</value> <value>false</value> </item> </response> </ajax-response>
|
选择框更新:服务器端 此示例的服务器端代码异常简单。如果合适,AjaxTag API 具有某些内置的 HttpServlet 子类可供您所用,此外,还有一些实用类用来生成简单的 XML 响应(参见清单 10): 清单 10. 取自 DropdownServlet 的代码片段,展示了如何创建对某个 Ajax 请求的适当 XML 响应
public String getXmlContent( HttpServletRequest request, HttpServletResponse response) throws Exception { String make = request.getParameter("make"); CarService service = new CarService(); List<Car> list = service.getModelsByMake(make); AjaxXmlBuilder xml = new AjaxXmlBuilder(); for (Car car:list) { xml.addItem(car.getModel(),true,car.getModel(),false); } return xml.toString(); }
|
我对清单 10 中的代码进行了简单的修改以便简化它。正如您所见,要创建可由 AjaxTags 客户端 JavaScript 处理的合适响应,所需的代码不多(而且还可以进一步减少)。
结束语 正 如所见,AjaxTags 让您可以轻松地向新的或现有的 Java Web 应用程序中添加功能强大的 Ajax 特性。有了 JSP 标记对下拉框修改、切换、选项卡面板、重用以及其余的诸多特性的全面支持 — AjaxTags 无疑成为了创建简捷、细致的 Ajax 应用程序的绝佳选择。使用像 AjaxTags 这样的 Ajax 库可以极大地改善 Web 应用程序的可用性和用户体验,而且还能减少所需的服务器负载和带宽。
参考资料 学习
- 您可以参阅本文在 developerWorks 全球站点上的 英文原文 。
- 参阅有关 AjaxTags 和 AppFuse 的简短教程。
- 阅读另一个 简短的 AjaxTags 教程。
- 若想学习如何开发和设计基于 Ajax 的 Web 应用程序,请参阅 “使用 Ajax 构建应用程序”(Naveen Balani 和 Rajeev Hathi,developerWorks,2005 年 11 月)。
- 在 “Ajax 和 XML: 五种 Ajax 反模式”(Jack D. Herrington,developerWorks,2007 年 3 月)中了解需要避免的一些常见的编码实践。
- 在 “Ajax 和 XML: 五种常见 Ajax 模式”(Jack D. Herrington,developerWorks,2007 年 3 月)中了解可以应用到您自己的工作中的 5 个常见 Ajax 设计模式。
- 这个由 5 部分组成的 “面向 Java 开发人员的 Ajax: 构建动态的 Java 应用程序”(Philip McCarthy,developerWorks,2005 年 9 月)系列给出了令人耳目一新的、利用 Ajax 创建动态 Web 应用程序体验的方法。
- The developerWorks XML 专区 中有能让您立即开始使用 XML 的大量资源。
- 查阅 developerWorks Ajax 资源中心,这里几乎囊括了关于 Ajax 编程模型的所有信息,包括各种文章和教程、论坛、博客、wiki、活动和新闻。
获得产品和技术
- 访问 Sourceforge 上的 AjaxTags Web 站点。
- 从 Apache.org 下载 Apache Tomcat。
讨论
- 参与论坛讨论。
- 浏览 developerWorks XML 专区论坛。
关于作者
|
|
|
Daniel Wintschel 的每天都异乎寻常。但很多时候,他都在帮助一些小型或中型的公司增强实力和提高效率。通常他都会沉浸在用 Java 或 Ruby 编写 Web 应用程序的乐趣中,他非常钟爱编写代码。 |
|