在过去的几年中,Java 平台技术取得了一些惊人进展。但这项技术在某些方面的广泛应用和它最初的设计目标完全不同。Java 平台技术最初是希望通过客户端运行 Applet 和 application,来给网页增加交互性。而现在该技术最常见的用途却是基于服务器的 J2EE 系统。为了让 Java 平台在客户端发挥它的最大潜力,人们开发了许多新技术。由于企业系统逐渐被互联网应用程序所取代,掌握这些新技术也就非常必要。在这篇文章中,你可以看到如何利用新旧技术来达到此目的。
Applet 遇到什么问题?
当 Java 平台首次发布的时候,就预示着一种新方法,能够将互联网从静态的简单网页集合,提升到具有交互性的高级层次。Java 创始者的最初目的是为开发者们提供一些方法,创建可以在任何客户端机器上运行的小程序。这些程序还能够将客户端进程与服务端数据相结合,给客户提供高度的交互体验。
然而在某些地方,Java 为客户端所承诺的许多特性得不到实现。导致这个不幸的可能原因包括以下几种:
公司防火墙通常阻止 Java Applet 的通过。
许多客户端没有提供完全兼容的 Java 虚拟机。
安全设置不允许使用 Applet 来执行很多有用的规则。
浏览页面时,下载一个完整用户界面所需的开销,常常令许多用户对 Java Applet 望而却步。
必须为不同系统以及不同的平台,重新实现许多用户界面函数(打印,文件管理和其他一些类似任务)。这也是许多开发人员避免使用 Java Applet 的原因。
随着互联网上电子商务的成长,终端用户的处理能力有所增加,对通讯带宽的需求更是迅猛增长。在客户端组件中使用 Java 技术再度成为一件很有诱惑力的事情。然而,我们需要研究一种新方法,既能够利用客户端的程序,又不必遇到类似于使用 Java Applet 制作 ad-ware 和滚动新闻栏时所面临的障碍。通过新旧技术的结合使用,甚至融合某些几乎被快速奔跑的“互联网时代”所淡忘的旧技术,就能够减轻这些问题。
人们为什么称之为JavaScript
在客户端使用 Java 技术时,最为忽略的一点便是 Java Applet 和 JavaScript 之间的结合。JavaScript 标准早就为脚本提供了调用 Applet 类的方法,而 Applet 也能够调用脚本的函数。这种结合让我们能够发挥这两种技术的最大长处。我们开发并保持所需要的功能性,而将用户界面的设计交给网页开发人员来处理。此外,利用这种结合,还能够增加用户与服务器的交互程度却留下很少客户端参与的痕迹。
JavaScript 标准中的 LiveConnect 技术(参看资料部分),允许在网页中使用脚本来调用 Applet 方法。只要简单地创建所需要的 Java 类,并允许 JavaScript 脚本的开发者访问这个类中的方法便可。而 com.netscape.JSObject 类则使我们能够访问 JavaScript 函数和对象。这就提供了一种在 Java 代码中调用 JavaScript 函数的方式,直接令网页发生相当有趣和重要的变化。有了 JavaScript 和 Java Applet 之间的联系,那些 JavaScript 或 Java Applet 无法单独执行,但结合这二种方法却能完成的任务就能够被解决。而且,此二者的结合通常还能够减少网页提交到服务器的时间,从而减少了用户等待时间,服务器处理时间以及服务端的会话状态维护开销。考虑下列例子:
在用户填表的同时,后台线程使用 Java Applet 来在服务端数据库中寻找地址或电话号码信息。
当 SSL 不适合使用时,利用 PKI 技术来为系统间的通讯加密。
使用 DSA 标准来对请求签名,为消息内容和发送者提供强大的确认功能。
使用 Java Applet 向服务器数据库提交日程改变,并在客户端的背景上更新本地日程显示。不需要不断对所有日程做更新,并且最大程度地缩短这个改动生效所需的时间。
结合使用 Java Applet 和 JavaScript 代码进行动态显示,不断更新浏览器文档中的内容;这种结合允许我们不必为每个所想象得到的客户端平台都写一段打印例程,也能够将内容打印出来。
清单 1 阐述如何使用 JSObject 和 LiveConnect 来验证一个电话号码,同时将该号码转化成标准格式。注意到这只是一个例子代码,所以我在服务器连接方法中略去若干必须的函数调用,以便简化这个清单。这个例子是当电话号码输入框内容发生变化时,在 JavaScript 中调用 Java Applet 函数。于是 Java Applet 就访问服务器,获得这个电话号码的标准格式字符串,并将该字符串返回到隐藏框(hidden field)里。真正实现此任务的代码,应该用后台线程来实现服务器连接和电话号码验证,以便让验证过程对用户而言是透明的。这个例子还使用了另一项使客户端 Java 编程更为有趣的技术:HTTP 连接以及与服务器代码(特别是 servlet 和 JSP 网页)的结合。
基于服务器的资源
那些必须存放在服务器上的资源会怎样呢?这类基于服务器的资源包括地址验证,运输费用计算,以及信用卡验证等。支持数据以及要求高安全度的处理必须放在服务端,但大部分的验证处理,数据转换以及费用计算过程可以迁移到客户端系统上。支持这一想法的几个 Java 语言特点包括:
Java 语言通过 HttpURLConnection 对象来为 HTTP 连接提供内在支持。同时利用 java.net 包的其他部分,为服务端代码与客户端代码之间的通讯提供一种方法,简单有效地生成数据或打包数据。
许多客户端的 Java Applet 代码实际上与那些在服务器上运行的代码是一样的。
现在我们可以将多种任务分配给服务器和客户机,从而减少服务器负载,甚至可能减少网络连接。具体如何分配这些任务将取决于系统的类型以及用户团体,但几乎所有的系统都会因为增加一些客户端处理而受益,例如:
Applet 类能够将数据从一系列格式转化到单一的 XML 字符串格式,这使得服务器更容易处理数据。
Applet 类可以进行数据压缩,即把那些将要上载到服务器的数据压缩,同时将这些数据分割成较小的数据包,从而进一步提高了可靠性。
当用户填写结帐表单时,Applet 类能够进行地址和运输费用的计算(在更大的基于服务器数据库中这类计算常常需要进行交互)。此方法能够减少最后结算所需要的时间,同时令用户在提交定单之前就能够看到正确的运输费用以及相应税金等信息。
为了发挥这个技术的最大优势,需要一些方法向那些返回指定数据的服务器发送请求。 Java servlet 恰好具有这种能力。许多开发者并未完全意识到 servlet 能够将任何一种数据作为响应并返回,而不仅仅限于 HTML 或是 XML。通过返回一系列连续的对象或一个压缩的数据包,servlet 能够执行例如地址确认或运输费用和税金计算等任务。同时,进行这些计算的客户端代码可以通过后台线程的运行来掩盖用户等待时间。清单 2 中显示了一个servlet,该 servlet 接收 HTTP 的带有 Zip 代码的 GET 请求,并返回运输费用的计算结果。同样出于令清单清晰明了的目的,在这里省略了若干非常重要的实际代码。
注意到我使用 ObjectOutputStream 对象来将整个目标图表写入待返回的响应中。content 类型需要设置成某些合适的值,同时将 content 处理句柄分配到客户端。这种方法能够返回一个 Java 对象,里面包含顾客运输、处理费用以及应缴税金的计算结果。如果这个对象只是与客户端后台线程进行通讯,用户就根本不会意识到他已经和服务器进行了一轮通讯。
节约时间的新技术
上述技术都已实现若干时间了,且大多数正在全世界各种不同的系统上应用着。前面我曾经许诺过要介绍一些新技术,现在是具体阐述它们的时候了。客户端上最有趣的 Java 新技术当属 weblet。IBM alphaWorks 的 DirectDOM 就是该技术的一个具体实现(参看资料部分)。DirectDOM 允许从 Java 代码中访问整个浏览器 DOM tree (2000年11月13日 W3C 建议为 DOM Level 2)。weblet 没有用户界面,必须通过操纵浏览器中的活动 DOM 文档来完成它的工作。许多原先需要复杂 JavaScript 代码才能实现的技术,通过这种方法都能够实现。必须注意到尽管 DirectDOM 是一项很有吸引力的技术,它仍处在 alpha 阶段,是不完善的,并且需要 Internet Explorer 或 Mozilla (M18) 的最新版本才能够运行。然而,此技术足以使你预测到不远的将来将会如何令人激动。一些可能实现的例子如下:
在充满了大量图形和视觉刺激的结算网页上,加入 weblet。那么在用户处理结算表格的多个步骤时,不需要每步都在表单与网页间切换,也能够与服务器通讯交换数据并完成结算。当结算完毕需要确认时,weblet 会将整个包提交到服务器,服务器就可以按照通常的结算处理步骤进行处理。
一个显示属性消息的网页。weblet 通过令页面空白来标记对应于打印或保存请求的响应,从而防止数据被不加区别地共享。
用户可以向互联网上的应用程序请求获得某些报告。报告的摘要信息会马上传送到,而 weblet 则使用后台线程下载该报告的详细信息。当用户对摘要中某行条目感兴趣时,只要用鼠标点击该条目,weblet 就能够立即响应鼠标动作,在这个条目的下方显示详细信息。这些具体信息是在摘要页面下载后,才被后台线程下载的。但是用户并不会注意到这一点。
另一个长些的例子,更清楚地展示了 weblet 如何工作。在 清单 3,发送给客户端的 HTML 页面和 清单 4,weblet 类的 Java 代码中,可以看到这个例子。尽管它不适合于生产环境也未完善,但依然很有用。这个例子下载一个很长的示范网页,其中含有两个表单和一个 weblet 标记。weblet 用一些介绍性的文本来替代这些表单,或在演示过程中切换这两个表单。
为什么要做这些?
为什么我们会关注客户端的 Java 技术发展呢?为什么不建立那些只为网络上计算机工作的系统,或是瘦客户系统,而在服务器上执行绝大部分的复杂计算工作?简单的说,是因为我们无法提供这样的服务器服务。倘若要在单独一个服务器空间中安装足够的处理程序,来支持大量客户端所请求的巨大处理负载,开销将是极其昂贵的,因此才开发了分布式系统模型 (n-tier 结构)。客户端的 Java 技术允许我们减少大型系统中的操作开销的同时,大幅度提高客户端的参与??减少用户与服务器之间通讯的回合数,提高交互层次,改善数据的确认速度。客户端的 Java 技术还可以帮助我们实现一些服务器难以单独完成的任务,比如基于标记 (token-based) 的数字签名等。即便是单一的开发平台,企业版的 Java 2 也提供了强大的体系结构。可以将客户端 Java 技术与支持 Java 2 平台的服务器相结合,不能充分利用这个优势将非常遗憾。