Flex企业应用开发实践学习笔记(八)——Flex on Java企业应用架构

来源:互联网 发布:软件开发计划书模板 编辑:程序博客网 时间:2024/06/08 15:16

实践证明,软件企业的可复用平台越完善,覆盖领域越广泛,那么软件企业的开发能力就越强,其开发效率和产品质量都会得到很大的提高。

企业应用的主要分层:

【展现层】主要负责信息展示和人机交互的相关逻辑,“展现层”接受用户输入并将用户的意图转换为对“领域层”或者“数据源层”逻辑应用。

【领域层】主要完成企业应用业务逻辑,是系统的核心部分。也称为“业务逻辑层”,主要解决应用所针对的业务领域的问题。该层负责校验来自“展现层”的输入数据,根据“展现层”用户指令进行业务逻辑的处理,调用“数据源层”的逻辑实现数据的访问和持久化。

【数据源层】负责数据的提取和持久化,数据可能来自于数据库或者消息系统。对于绝大多数的企业应用来说,数据层主要负责同数据库系统交互。

---------------客户端Flash虚拟机----------

 -                   【展现层】                         -

---------------------------------------------------

---------------服务器端Java虚拟机---------

             -                   【领域层】                          -

             -                   【 数据源层】                     -

            -----------------------------------------------------

Flex + Java所开发的企业应用系统是异构的分布式系统,这种分构式系统给我们带来了一下需要思考的问题。

1)异构的客户端系统和服务器端系统如何通信?

2)如何保持分布式的客户端系统和服务器端系统之间的状态一致性?


在Flex中,基于HTTP协议访问服务器的通信组件有三个:

【a】HttpService   ( mx.rpc.http.mxml.HTTPService )

【b】WebService   ( mx.rpc.soap.mxml.WebService )

【c】RemoteObject  ( mx.rpc.remoting.mxml.RemoteObject )

使用HttpServiceWebService无需第三方框架,在服务器端直接编写相应的服务即可,但是Flex客户端和服务器之间传递的都是XML数据,客户端和服务器端处理的也是XML数据。对于企业应用来说,客户端和服务器端交互的数据量往往很大,因此使用XML作为数据交换的格式会减低传输效率和转换效率。同时,处理XML数据的代码也远比处理对象的代码繁琐,并且难以阅读和调试。所以在企业应用中采用HttpServiceWebService进行通信的部分较少,即使使用者两个组件,也应当用来传递少量、数据格式不易发生变化的数据。

在我们企业应用开发中,Flex客户端与后台服务器之间的大量通信都采用RemoteObject完成的。RemoteObject组件在“第三方软件”的配合下,能够调用后台服务器对象上的方法,比如java对象或者.net对象上的方法,从而实现客户端与服务器端的通信。在客户端使用RemoteObject可以直接将ActionScript对象作为调用的参数和返回结果。(Adobe公司定义了一种二进制数据格式AMF(Action Message Format),用户客户端与服务器端的数据交互,AMF数据格式的规范已经公开。有兴趣的读者可以到以下网址下载AMF规范:http://download.macromedia.com/pub/labs/amf/amf3_spec_121207.pdf。)

其实,使用AMF格式交换数据与使用XML进行数据交换的主要区别在于:【a】AMF二进制数据的转换和传输效率更高,同时需要“第三方软件”用于解释AMF格式数据。Flex客户端RemoteObject组件与服务器端通过HTTP协议传递AMF格式的二进制数据进行通信的大致过程如下:

1):客户端RemoteObject将调用参数中的ActionScript对象序列化为AMF数据格式然后发出调用请求。

2):服务器的“第三方软件”获取HTTP请求流。

3):服务器的“第三方软件”对HTTP请求流进行解析,并且建立响应消息。对HTTP请求流进行解析,解析过程包括解释AMF格式数据,将ActionScript对象的AMF数据按照事先确定的协议“反序列化”为服务器对象,比如Java对象,然后用这些参数调用客户端指定的服务器对象上的方法。

4):服务器的“第三方软件”将调用结果“序列化”为AMF格式的数据流。

5):服务器发送HTTP响应给Flex客户端。

6):Flex客户端解释AMF格式数据流,将调用结果序列化为ActionScript对象。

7):下面我们给出一段Flex官方文档代码来展示RemoteObject对象的使用:

  1. <?xml version="1.0"?> 
  2. <!-- fds\rpc\ROInAS.mxml -->   
  3. <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"> 
  4.     <mx:Script> 
  5.         <![CDATA[  
  6.             import mx.controls.Alert;  
  7.             import mx.rpc.remoting.RemoteObject;  
  8.             import mx.rpc.events.ResultEvent;  
  9.             import mx.rpc.events.FaultEvent;  
  10.             [Bindable]  
  11.             public var empList:Object;            
  12.             public var employeeRO:RemoteObject;  
  13.             public function useRemoteObject(intArg:int, strArg:String):void {  
  14.                    employeeRO = new RemoteObject();  
  15.                 employeeRO.destination = "SalaryManager";  
  16.                 employeeRO.getList.addEventListener("result", getListResultHandler);  
  17.                 employeeRO.addEventListener("fault", faultHandler);  
  18.                 employeeRO.getList(deptComboBox.selectedItem.data);  
  19.             }  
  20.             public function getListResultHandler(event:ResultEvent):void {  
  21.                  // 远程调用成功所要完成的处理。  
  22.                 empList=event.result;  
  23.             }  
  24.  
  25.             public function faultHandler (event:FaultEvent):void {  
  26.              // 调用失败所要完成的处理。  
  27.                 Alert.show(event.fault.faultString, 'Error');  
  28.             }  
  29.         ]]> 
  30.     </mx:Script> 
  31.     <mx:ComboBox id="deptComboBox"/> 
  32. </mx:Application>

在上面的代码中,我们重点关注加黑的代码,首先看一下函数useRemoteObject,这个函数中首先使用语句:

  1. employeeRO = new RemoteObject(); 

创建了一个RemoteObject对象employeeRO。然后通过语句:

  1. employeeRO.destination = "SalaryManager"

将RemoteObject对象的destination属性赋值为一个字符串"SalaryManager",destination属性表示远程对象调用的“目的地”,请求发送到服务器端后,服务器端的“第三方软件”接收到请求后会检查配置文件,找到destination值所映射的“服务器端组件”,从而可以调用该组件上的方法。接下来使用语句:

  1. employeeRO.getList.addEventListener("result", getListResultHandler); 

设置远程服务调用成功时的处理方法,使用语句:

  1. employeeRO.addEventListener("fault", faultHandler); 

设置远程服务调用失败时的处理方法。最后,使用语句:

  1. employeeRO.getList(deptComboBox.selectedItem.data); 

以deptComboBox.selectedItem.data为参数,调用destination 属性所映射的“服务器端组件”的getList方法。这里,“服务端组件”必须有一个名为getList的公开方法,调用“服务器端组件”的getList方法是异步调用,因此它不会阻塞线程来等待调用结果的返回,调用结果的返回时会在getListResultHandler方法中进行处理。在getListResultHandler方法中,我们看到语句:

  1. empList=event.result; 

该语句表示远程调用所返回的结果(event.result)可以直接赋值给ActionScrip对象。当然,后端返回的对象类型与Flex客户端的ActionScript对象类型要满足“第三方软件”所规定的对象类型之间的“映射”规则,这样,Flex就可以把后台返回的AMF数据流自动地序列化为ActionScript对象。

在上面的论述中多次提到了“第三方软件”,要使用RemoteObject组件进行远程方法调用,那么必须在服务器上部署和配置相应的“第三方软件”。“第三方软件”有两个最基本的作用:

【1】服务器端对象序列化为AMF格式数据和将AMF格式数据反序列化为服务器端对象。

【2】将客户端的请求映射为服务器端相应对象上的方法调用。

由于AMF规范已经公开,因此,有很多“第三方软件”支持不同的后台服务器端语言,在.net平台下比较著名的“第三方软件”为Midnight Coders WebORB(http://www.themidnightcoders.com/)。我们所关心的Java平台下的“第三方软件”有Adobe官方商业收费软件LifeCycle  Data  Services(LCDS)和Adobe官方开源软件BlazeDS。

BlazeDS是LCDS的开源版,只不过BlazeDS不具备LCDS的一些高级功能,比如:

【高级客户端-服务器数据同步功能。】

【冲突检测/解决。】

【Adobe AIR应用的离线数据管理服务。】

【由RIA生成PDF等。】

使用BlazeDS与LCDS进行企业应用开发的配置完全一样,因此,在不需要LCDS高级功能的情况下,完全可以使用BlazeDS替换LCDS作为一种廉价方案,必须使用LCDS高级功能时,用户可以追加投资购买LCDS,因此基于BlazeDS企业应用可以很容易升级为基于LCDS的企业应用,这也是我们选择BlazeDS作为配合RemoteObject远程调用的“第三方软件”的主要原因。

因此,使用Flex+Java开发企业应用,我们主要使用RemoteObject+BlazeDS实现Flex端与Java端的通信。读者可以从以下网址查看BlazeDS的信息和下载BlazeDS框架:http://opensource.adobe.com/wiki/display/blazeds/BlazeDS/。

总之,使用RemoteObject+BlazeDS作为Flex端同Java服务器端的通信框架有如下优点:

【a】以二进制的AMF协议传递数据,转换和传输数据的性能高于XML格式,读者可以参考http://www.javaeye.com/news/3000一文中对几种RIA应用数据传输协议性能的比较。

【b】使用RemoteObject+BlazeDS能够实现Flex对象与Java对象之间的自动转换,更加有利于开发者编程。

【c】使用开源框架BlazeDS所开发的企业应用可以更容易地升级为采用高端商业软件LCDS作为数据通信框架的企业应用。


原创粉丝点击