无论是采用 Adobe AIR 技术的桌面应用程序 ,还是结合 Flash Player 使用浏览器的应用,在需要加载或处理数据的时候往往都需要连接到服务器。在采用 Adobe Flex 或 Flash CS3 来开发应用程序的过程中,应用程序与服务器间交互的实现方式有很多选择。服务器本身除了可以运行 Java、ColdFusion、.Net、 PHP、Ruby 等某种服务器端技术之外,还必须具备网络通信的能力,这为 Flash Player 中运行的应用或 Adobe AIR 应用的客户端与服务器端间的交互奠定了基础。通常,两者间的通信采用的是 HTTP 协议 -- 也就是 web 浏览器加载 web 页面和应用时所采用的协议。但是,HTTP 协议下采用不同的数据传输方式会带来应用性能和开发效率的天壤之别。
很多在 Abode AIR 或 Flash Player 中运行的应用都采用 XML-over-HTTP 技术(比如 SOAP、REST 等)在客户端和服务器之间传输数据。这个方法很简单,也很容易搭建。无论是哪种服务器端技术都很容易应用 XML,因为 XML 完全是一个基于文本的协议。在必须实现透明协议的时候,XML 是完美的选择。比如,Flickr 的 web 服务在 HTTP 传输之上采用的就是 REST 风格的 XML。这样一来,无论是谁采用哪种技术都可以简单地通过向 Flickr 发送简单的基于文本的请求来与 Flickr 交互。Flickr 的回复是简单的 XML,开发者可以轻松地解析这个 XML 回复,使用其中的数据。像 XML 这样基于文本的协议的缺点是额外的数据抽象层的编写与维护工作相对很沉重。此外,如果数据需要序列化和反序列化,那么这个数据抽象层在客户端和服务器端都会占用很多资源(参见图 1)。
图 1. AMF 减少封送处理的数据层
Flash Player 可以支持另外一种传输协议,这个协议能够缓解由基于文本的协议导致的传输瓶颈问题,能够帮助开发者以更简单的方式与服务器交互。这就是 AMF(Action Message Format)。它是一个二进制格式的协议,能够替代用于传输 XML 的基于文本的协议而在 HTTP 协议之上交换数据。采用 AMF 的应用中,数据抽象层完全可以省去,客户与服务器间的通讯效率比传统的应用基于文本的协议传输要高得多。 Census RIA Benchmark 应用程序可以证明 AMF 带来的性能优势。
过去几年里,大量旨在提供 AMF 实现的开源项目蜂拥而至,这些项目与 Macromedia 之前一个叫做 Flash Remoting 的产品很相似。由于这些开源项目,无论是 PHP、Java 还是其它技术的开发人员都得以能够在他们的应用中采用 AMF。Flex 1.0 版本发布的时候,就涵盖了 AMF 相关功能。Flex 发布版本 2 的时候同时包含了 XML 和 AMF 的相关功能,但服务器端的 AMF 相关功能却特别转移到 Flex Data Services 这个新产品中。Flex Data Services 在集成到 Live Cycle 产品系列中的时候又被重新命名为 LiveCycle Data Services。针对单个 CPU 服务器的 LiveCycle Data Services ES Express 是免费的,但针对拥有多个 CPU 服务器的产品则收费很高,这使得一些开发者在选择 AMF 的时候望而却步,其中一些人也因此干脆转而选择一些非标准的 AMF 实现。
2007 年十二月,Adobe 做出了两个巨大的决策,让所有人都能够使用 AMF。第一个决定是公开 AMF 规范。规范公布以后,所有项目都能按照规范来实现 AMF,而不用再对协议做反向工程。无论 back-end 采用的是 Java、ColdFusion、PHP、.Net、Ruby 还是其它技术,AMF 的实现都只需要遵守规范即可。另一个决策是以 BlazeDS 项目的方式开源 LiveCycle Data Services ES 中的部分技术。
BlazeDS 中包含了 AMF 的 Java 实现,可以用来与服务器端的 Java 对象远程交互,也可以用来在客户端之间传递消息。开发人员可以借助 BlazeDS 的远程技术简单地调用 POJO、Spring 服务或 EJB 方法。开发人员可以通过其消息系统从客户端向服务器端发送消息,当然也可应从服务器端向客户端发送消息。BlazeDS 也可以与其他一些消息系统结合使用,比如 JMS、ActiveMQ。由于其远程技术与消息系统采用的方式是在 HTTP 协议上传输 AMF 数据,BlazeDS 因此在性能上拥有很大优势,同时也避免了额外的数据抽象层的处理工作。BlazeDS 在很多基于 Java 的应用服务器环境下都能正常工作,这些服务器包括 Tomcat、WebSphere、WebLogic、JBoss 以及 ColdFusion。此外,无论是 web(在 Flash Player 中运行)还是桌面(在 Adobe AIR 下运行)的 Flex 应用程序中,BlazeDS 的使用都很简单。
开发人员现在可以从 Adobe Labs 站点上下载预发布版本,将 blazeds-samples.war 文件部署到任何一个 servlet 容器中,就开始你使用 BlazeDS 开发的旅程了。这个 web 应用包中提供了很多预配置的示范应用,所有这些应用都可以通过 http://localhost:8080/blazeds-samples/ (端口号由你所使用的应用服务器和服务器配置所决定)来访问。
你可以遵循下面的步骤向应用程序中引入 BlazeDS 远程服务:
- 创建一个新的 POJO Java 类,这个类中需要包含你想要从 Flex 应用访问的方法
- 在 remoting-config.xml 文件中配置 BlazeDS 的远程终端
- 创建一个使用 RemoteObject 类的 Flex 应用
若要使用 BlazeDS 消息服务,则需要下列步骤:
- 在 messaging-config.xml 文件中创建消息服务的终端
- 创建一个使用 Producer 和 Consumer 类来接收消息的 Flex 应用
- 通过注册 Consumer 的消息 feed 来监听消息。
这下就可以使用 BlazeDS 高效地向 back-end 的 Java 类发送远程请求了,也可以应用 BlazeDS 的消息系统了。接下来,我们将在 Eclipse 和 Flex Builder 环境下详细讨论上面提及的步骤。在开始之前,你需要安装几个软件:
- Eclipse 3.3 Classic
- Flex Builder 3 Beta 3 (Eclipse 插件)
- 任何 Java 应用服务器(Tomcat、JBoss、WebLogic、WebSphere 等)
- BlazeDS
创建一个简单的远程应用:
-
从 BlazeDS 中将 blazeds.war 解压到应用服务器的部署目录下。比如,在 JBoss 下,解压到 /server/default/deploy/blazeds.war
-
启动 Eclipse 和 Flex Builder
-
创建一个新的 Java 项目来配置 BlazeDS,向 web 应用中添加 Java 类。
-
将项目命名为“blazeds_server”
-
从现有资源中创建该项目,使用先前部署的 BlazeDS WAR 的 WEB_INF 文件夹路径,比如:/server/default/deploy/blazeds.war/WEB-INF/
-
在 build 路径下添加 src 目录
-
将 WEB-INF/classes 目录作为输出目录
-
创建一个名为 HelloWorld.java 的新 Java 类,类的定义为:
public class HelloWorld {<br></br> public String sayHello(String name) {<br></br> return "hello, " + name;<br></br> }<br></br> }
7. 修改 BlazeDS 配置,使它支持向 HelloWorld 远程发送请求。这需要在 WEB-INF/flex 文件夹下的 config.xml 文件中添加消息终端的配置,具体配置可参照如下代码:<destination id="HelloWorld"><br></br> <properties><br></br> <source>HelloWorld</source><br></br> </properties><br></br> </destination>
-
启动应用服务器,确定 web 应用可以通过下面这个地址访问(端口号由应用服务器配置决定): http://localhost:8080/blazeds/
(假如服务器配置并未允许显示目录下的内容的话,你会得到 404 错误,但这没什么关系) -
创建一个新 Flex 项目
-
将项目命名为“testHelloWorld”,应用服务器类型则选择“J2EE”
-
选择“Use remote object access service”和 LiveCycle Data Services
-
将 WAR 文件部署的位置声明为根目录
-
将根 ULR 声明为: http://localhost:8080/blazeds(端口号由应用服务器配置决定)
-
将上下文根目录声明为:/blazeds
-
确定配置并点击“完成”
-
创建 Flex 应用,将下列代码替代 testHelloWorld.mxml 中的内容:
<?xml version="1.0" encoding="utf-8"?><br></br> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"><br></br> <mx:RemoteObject id="ro" destination="HelloWorld"/><br></br> <mx:TextInput id="n" change="ro.sayHello(n.text)"/><br></br> <mx:Label text="{ro.sayHello.lastResult}"/><br></br> </mx:Application>
-
运行该应用,在文本框中输入你的名字,文本框的正下方你可以看到“hello, < 你的名字 >”,如下图所示:
注释:该 Flex 应用使用了 RemoteObject 类库来与支持 BlazedDS 的服务器通信。当用户在文本框中输入内容的时候,文本框的 change 事件促使 RemoteObject 向服务器发出请求。于是,服务器紧接着向定义了的远程终端 Java 类发送请求,这个时候也有可能调用 Spring 服务或者 EJB session bean,但本例调用的是 POJO。本例中,POJO 的返回值仅仅是在向它发送的值之前添加了“Hello,”的字符串。在对象返回值的时候,这个返回值会系列化到 AMF 中,进而返回给 Flex 应用。然后,RemoteObject 类库将该值赋值给 ro…lastResult 属性(本例中,则是ro.sayHello.lastResult
)。最后的结果也可以通过 RemoteObject 上的 result 事件获得。数据绑定的过程中,文本框的标签就相应显示为 POJO 返回的字符串。BlazeDS 同时也支持 Java 对象类的传递。
下一步,我们将创建一个使用 BlazeDS 消息系统的 Flex 应用。
-
首先,在 WEB-INF/flex 目录下的 messaging-config.xml 文件中添加消息终端配置。添加下面这个终端:
<destination id="chat"/>
消息终端的配置使得消息系统能够将消息转发给正在监听该终端消息的客户。消息终端可以配置持久时间和网络参数,同时也可以连接到其它的消息系统,比如 JMS。 -
重新启动应用服务器,这样一来,BlazeDS 会配置新的消息终端。
-
创建一个新 Flex 项目
-
将项目命名为“testChat”
-
应用服务器类型选择“J2EE”
-
选择“Use remote object access service”和 LiveCycle Data Services
-
将部署的 WAR 文件位置声明为 Root 目录
-
将根 URL 声明为: http://localhost:8080/blazeds(端口号由应用服务器配置决定)
-
将上下文根目录声明为:/blazeds
-
确定配置并点击“完成”
-
创建一个简单的使用消息系统的聊天应用程序,用下列代码替代 testChat.mxml 中内容:
<?xml version="1.0" encoding="utf-8"?><br></br> <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="cons.subscribe()"><p> <mx:Script></p><br></br> import mx.messaging.messages.AsyncMessage;<br></br> </mx:Script><br></br> <mx:Producer id="prod" destination="chat"/><br></br> <mx:Consumer id="cons" destination="chat" message="c.text += event.message.body.msg + '\n'"/><p> <mx:TextArea id="c" width="300" height="300"/></p><br></br> <mx:TextInput id="m"/><br></br> <mx:Button label="Send" click="prod.send(new AsyncMessage({msg: m.text}))"/><p> </mx:Application></p>
-
运行该应用。在页面底部的文本框中输入一条消息,点击“Send”。确定所发送的消息正确显示在第一个文本域中,同时确定在打开多个浏览窗口的前提下,消息也可以在这些窗口间传递。
注释:Producer 对象允许 Flex 应用向消息系统中发送消息。另外,还有一个 Java API(本例中没有用到)也可以用来向服务器上的消息系统发送消息。通过第三方适配器或服务器自带的 JMS 适配器,你也可以将自身的消息系统连接到其它的消息系统,但默认配置并不支持它与另外的消息系统的连接。用户点击“Send”的时候,某个匿名对象会创建一条新消息,并将消息体中的 msg 属性值设置为文本框中输入的内容。由于消息的类型是 AsyncMessage,所以 AsyncMessage 类是必需引入的。Consumer 对象使得 Flex 应用能够监听消息。应用会在其初始化的时候在消息系统中进行注册,之后,一旦收到消息,Consumer 上的事件处理器则会将从消息体中取得聊天消息显示在文本域中。
BlazeDS 和 AMF 的使用可以帮助减短开发周期,推动应用运行的速度。何不尝试一下 BlazeDS,我们很期待你的反馈。在 Adobe Labs 站点的 BlazeDS 页面上,你可以找到很多 BlazeDS 的相关内容以及 AMF 的公开规范说明。
关于作者
James Ward 是 Adobe 的 Flex 技术传道士,也是 Adobe 在 JSR 286、299 和 301 规范制定中的 JCP 代表。他喜欢登山,也喜欢编程,因为两者都能给他带来无尽的发现、漂亮的解决方案、巅峰与峡谷。出于对登山冒险的热爱,他去过很多地方。同样,技术也带给他许许多多的冒险经验,比如九十年代早期的 Pascal 和 Assembly;Perl、HTML、九十年代中期的 JavaScript;之后就是九十年代后期的 Java 和相关的开发框架。如今,他主要在以基于 Java 的 back-end 的基础上使用 Flex 来创建华丽的前端应用。在加入 Adobe 之前,James 为 Pillar Data Systems 开发了市场和客户服务的富客户端 portal 应用。James Ward 的博客是: http://www.jamesward.org 。
hashank Tiwari 是 Saven Technologies 的主要技术开发员。Saven Technologies 的总部位于芝加哥,主要为银行及金融服务机构提供由前沿技术开发的业务解决方案。Shashank 是一个多产的技术开发员、作者以及演讲者,他在 JCP 的表现极为积极,并且是 JSR 274、283、299、301 和 312 规范的专家组成员。他经常在使用的编程语言至少有一打,包括 Java、ActionScript、Python、 Perl、PHP、C++、Groovy、JavaScript、Ruby 和 Matlab。他在 O’Reilly Network 的博客也很受欢迎。最近,他正忙于创建使用了 Flex 和 Java 的 web 2.0 应用。 www.shanky.org 上有他更多的资料。
阅读英文原文: Building Web and Desktop Applications with BlazeDS and AMF
评论