扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:Mark Eagle 来源:IT专家网 2008年6月1日
关键字: Flex MACROMEDIA 整合 java
当使用RIA时Struts不只是您唯一想的事了。 熟悉这类型技术需要时间。 在经历这些曲折以后, 最大的问题是Java服务器端组件的综合化。 这也并非是针对RIA概念。
Flex与业务层集成
前面我们已经讨论了一些表示层相关的,下面我们讨论其它层在我们的应用结构是怎么受影响的。我们已经重置了我们的表示层组件; 我们怎么把它与业务层集成在一起呢?
Flex是一个可扩展的RIA 框架,它提供了很多方式与您的J2.EE 组件通信。Flex提供了HTTP 通信,万维网服务通信,还有Macromedia 的私有的AMF (ActionScript 传讯格式化) 网关。AMF 网关是一个高性能二进制协议,它近似于Flash remoting协议。远程对象运用HTTP 协议被发送到AMF 网关。Flex为每个这些通信协议提供MXML 标签, 这样一来极大的减少编制程序复杂度。 此外, Flex允许您以或异步或同步方式对您的企业等级启用远程调用。 通过使用一种异步远程购买权, 用户就能够对客户机进行一些操作并且即使当发生在传统万维网应用中时也不被拦截。 您能阻拦用户与使用同步调用的UI交涉。
让我们来考虑一下怎么让Flex和我们的业务综合化层集成呢。 为这我们将使用Spring框架作为我们的综合化层, 但这对您选择实施什么综合化层并没有限制。让我们假设一下您有您的服务运行在Spring microcontainer里, 并且您需要由Flex调用远程对象。
因为Flex对Spring完全不了解,您也许可以考虑添加一个separate, 即一个薄层作为代表您的service components。 并且, 因为Spring对Java接口起到了很大作用,所以我们可以建立一个代表对象,这个代表对象实施着和Spring服务一样的Java 界面。 这些代表对象将提供一个减弱了的网关,它从Flex和综合化层中分离。 您需要做的唯一的事是在Flex配置文件中配置这些对象因此他们能与AMF 网关共同操作。 这里有一个实例将说明代表对象是怎样被配置在server-side flex-config.xml Flex配置文件里的:
<object name="OrderBusinessDelegate">
<source>
com.meagle.flexro.FlexBusinessDelegate
</source>
<type>stateless-class</type>
<use-custom-authentication>
true
</use-custom-authentication>
<allow-unnamed-access>
false
</allow-unnamed-access>
<roles>
<role>OrderUser</role>
<role>Admin</role>
</roles>
</object>
初看Flex你会发现它一些有附加能力,类似于像设置安全性啦,决定委派对象是否申明啦。当Flex发一个远程的对象呼叫到内层时,它将会干扰一个Flex的委派Java对象.委派对象将会负责对呼叫内层或者服务层 (比如Spring).作为结果的对象将通过AMF网关返回到Flex客户端,这个对象被称为ActionScript对象.这里是一个MXML代码的例子, Flex客户端用MXML代码来远程调用并将结果存储到一个数据模式中.
<mx:RemoteObject id="soapro"
named="OrderBusinessDelegate"
protocol="https"
showBusyCursor="true">
<mx:method name="saveNewOrder"
result="saveNewOrder_result(event)"
fault="faultHandler(event.fault)"/>
<mx:method name="findOrderById"
result="findOrderById_result(event)"
fault="faultHandler(event.fault)"/>
<mx:method name="updateOrder"
result="updateOrder_result(event)"
fault="faultHandler(event.fault)"/>
</mx:RemoteObject>
<mx:Model id="roModel" >
<!-- The object graph for the Order object
will be stored here -->
<Order/>
</mx:Model>
图3. Overview of the AMF gateway. package com.meagle.bo; import java.util.ArrayList; /** // other fields and getter/setter methods not /** public function Order(){} public static var regClass = var id : Number; // other fields and getter/setter methods not 在ActionScript Order对象里你应该注意Object.registerClass这个特别方法。AMF 网关用这个Object.registerClass 方法在Java 和 ActionScript之间来拆整对象。这个方法把客户端的ActionScript 类注册到对服务器端的Java 类。因 为这些对象是很相似的,所以你在一个稍微不同的格式里不想重写你的域对象也是可理解的。像XDoclet 和蚂蚁之类的工具允许你自动地产生这 些ActionScript 对象而不是手动地编码。现在你能像在Flex客户里的ActionScript equivalents操作你的Java对象了 Flex与持久层集成 在使用一个在web上定义好的耦合的体系结构的应用程序中,你不直接和你的持久层对话。使用Flex不应该改变这个体系结构。在大部分情况下,集成层将代替你和你的持久层对话。通常是使用Data Access Object (DAO)来完成的. Data Access Object (DAO) 是用来连接诸如数据库的永久存储的数据的。Flex客户端不直接访问集成层甚至不直接了解这个层,因为它构筑了一个紧密的联结。让我们用Hibernate来作为持久层的一个例子。 当在Macromedia's AMF gateway环境下使用Hibernate和远程对象时,会有一对错误。Hibernate用户知道你不能访问一个不含有已初始化Hibernate会话对象的集合。访问一个没有被初始化的动态代理对象的集合会导致运行时错误。The AMF 网关不知道如何特定的去寻找Hibernate动态代理对象。一个潜在的方法是面向方面的编程(AOP)。即将一个即将传送给AMF网关的对象作为委代对象,移除动态代理。这是一个包含传递结果对象给拦截器,反复寻找使用映射并没有被初始化的代理对象的过程。如果找到什么无用的代理对象或集合,将他们设置为null。这是一个cross-cutting关注,可以作为一个方面,进而使用AOP语言,比如JBoss AOP, AspectJ, Spring AOP等等。AOP拦截器应该被应用于业务代理层的对象。 图4显示的一个应用架构: 图4在代理对象传入AMF网关之前介绍了AOP拦截器 这进一步在高层减少了重复组件,比如集成层,持久层等等。 值得庆幸的是AMF网关不知道缓存双向对象,所以无限的递归循环不会在传送对象时发生。因此,在AMF网关上互相传递对象时,你可以完全保持这种关系。同时,因为对象是非连接的,并且会有拷贝,你需要使用Session.saveOrUpdateCopy(Object object)方法去保存一个对象。这个方法必须使用,因为被传回到AMF网关的对象不会在字节码信息上加入对Hibernate有益的信息。 验证 典型的J2EE web应用程序有许多种身份验证模式。它有可能是基于容器的身份验证模式,或者是一些自定义密码的用户验证。像Flex之类的RIA 服务器允许你在大多数的应用程序服务器上使用Flash客户端的自定义身份验证格式和基于容器的身份验证。此外,如果你看一看上面的业务授权结构的例子的话,你会发现,为了安全起见你可以分配任务给这些对象。甚至在AMF网关中还有很多异常分支,允许开发者们获取HttpRequest、HttpResponse和ServletConfig对象来改进您想使用的、带有授权对象的安全性。 总结 这篇论文引入了一些概念,目的是为了让您了解当您使用诸如Flex之类的RIA时的权衡和潜在的缺陷。不论你使用的是Flex还是其它的RIA工具,在构筑应用程序的时候都会考虑最重要的是什么。当评估一个RIA框架时,要确定它有足够的可扩充性来对应应用程序的需求。此外,在RIA和Java之间传送对象时,需要注意要谨慎的构筑综合性的问题。
import java.util.Collections;
import java.util.List;
* This object represents an order.
* @hibernate.class table="TestOrder"
* @author meagle
*/
public class Order {
private int id;
private double total;
private int version;
private String userName;
private List orderLineItems = new ArrayList();
// shown to save space
}
Here is the ActionScript equivalent:
* Generated Action Script Object
* for com.meagle.bo.Order. Do not edit!
*/
class com.meagle.bo.Order extends Object {
Object.registerClass("com.meagle.bo.Order",
com.meagle.bo.Order);
var orderLineItems : Array = new Array();
var total : Number;
var userName : String;
var version : Number;
//shown to save space
}
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者