• Flex通过RemoteObject访问远程Java对象


    访问远程Java对象

    为了实现对远程Java对象的访问,在服务器端,需要完成如下几个 步骤:

    1.      创建LiveCycle Data Service Web应用;

    2.      实现POJO Java类;

    3.      在LiveCycle Data Service Web应用中部署POJO Java类;

    4.      配置remote-config.xml文件,声明desination节点,指向POJO Java类。

    在客户端应用中,需要实现:

    1.      实例化RemoteObject对象,并设定destination等属性;

    2.      调用远程Java对象的方法,并传递参数;

    3.      注册RemoteObject对象的result和fault事件侦听器,实现侦听器方法以处理返回响应或者调用异常。

    我们已经在第17章的17.5.1节“创建服务器端 LiveCycle Data Service应用”(见第416页)中介绍过如何创建LiveCycle Data Service Web应用。因此,我们这里将从实现POJO Java类开始逐步实现访问远程Java对象。

    19.2.1  服务器端:实现POJO Java类

    使用POJO类作为远程Java对象

    我们当然不会在一本Flex书籍中讲解如何编写POJO Java类。我们须要在这里解释一下可以作为远程Java对象的Java类。

    只有所谓的POJO类能够作为远程Java对象。 POJO(Plain Old Java Object)简称为简单Java对象,通常包含了一系列get和set方法。通常所说的POJO Java类就是纯的Java对象,不实现任何Java对象模型、协议及框架,例如不能实现EJB标准。严格地说,POJO类不能继承其他父类,不能实现接 口。LiveCycle Data Service要求,作为LiveCycle Data Service远程服务的远程Java对象,其构造器不能接受任何参数,也就是说必须为零参数构造器。这样,LiveCycle Data Service才能够构造POJO类实例。

    然而,POJO类仍然可以作为后端业务逻辑服务的窗口,例如使用 POJO类访问JNDI,获取EJB服务等,以便进一步集成后端业务逻辑。

    POJO Java类的公共方法提供了远程服务。需要注意的是,LiveCycle Data Service保留了一些方法名,因此POJO Java类不能使用这些方法名,我们称这些方法为“保留方法”。保留方法是RemoteObject类或其父类定义的方法。

    保留方法包括:

    ·       addHeader();

    ·       addProperty();

    ·       clearUsernamePassword();

    ·       deleteHeader();

    ·       hasOwnProperty();

    ·       isPropertyEnumerable();

    ·       isPrototypeOf();

    ·       registerClass();

    ·       setUsernamePassword();

    ·       toLocaleString();

    ·       toString();

    ·       unwatch();

    ·       valueOf();

    ·       watch()。

    此外,作为远程对象的POJO Java类也不能使用“_”作为远程服务方法名的起始字母。

    19.2.2  服务器端:部署POJO Java类

    在我们使用HTTPService组件和WebService组 件,通过HTTPProxyService服务访问远程HTTP服务和Web服务时,远程服务并不一定要部署在LiveCycle Data Service服务器上。

    而调用远程Java对象,则与这种情况大不相同。提供远程服务的 Java类必须与Flex应用部署在同一LiveCycle Data Service的Web应用中。

    部署POJO Java类的唯一目的就是当客户端RemoteObject组件向LiveCycle Data Service发出访问请求时,LiveCylce Data Service能够找到对应的Java类。

    因此,我们须要把POJO Java类部署到LiveCycle Data Service的类路径中。我们可以直接将POJO Java类文件(.class文件)按照类包结构部署到Web应用的WEB-INF\classes目录下,或者将POJO Java类打包为Jar包(.jar文件),部署在WEB-INF\lib目录中。

    19.2.3  服务器端:配置remote-config.xml

    原始remote-config.xml文件

    lcds-root/webapps/ lcds目录中包含了空的remote-config.xml文件。我们先来看看原始的remote-config.xml文件。

    请参考图19-2,该图展示了原始的remote- config.xml文件,并对主要节点做了注释。

    图19-2  尚未配置目标的remote-config.xml

    配置远程服务目标

    在标 签<service></service>内,添加<destination>< /destination>标签来声明新的远程对象目标。

    下面的代码显示了包含一个destination定义的 remote-config.xml文件:

    <?xml version="1.0" encoding="UTF-8"?>

    <service id="remoting-service"

        class="flex.messaging.services.RemotingService">

        <adapters>

            <adapter-definition id="java-object"

                class="flex.messaging.services.remoting.adapters.JavaAdapter"

                default="true"/>

        </adapters>

        <default-channels>

            <channel ref="my-amf"/>

        </default-channels>

      

        <destination id="shoppingCart">

            <properties>

                <source>com.mark.pojo.shoppingCart</source>

                <scope>session</scope>

            </properties>

        </destination>

    </service>

    destination节点的source属性说明了远程对象 服务的目标,也就是远程Java对象。在设定source属性时,必须使用全路径java类名称来指向部署在LiveCycle Data Service类路径中的Java类。

    desitnation节点的scrop属性的可选值为 application、session和request,指定了远程对象实例作用域。

    如果作用域为request,那么服务器会为每一次请求都创建一个 远程Java对象实例,request是默认的作用域。

    如果作用域是session,服务器则为每一个会话创建一个共享的 远程Java对象实例。通常来说,连接服务器的每一个浏览器实例构成了一个会话。例如,如果我们启动Firefox来访问连接LiveCycle Data Service的Flex应用,启动的Firefox就是一个浏览器实例。在该Firefox浏览器中,如果打开其他标签页也访问同一Flex应用,那么 这些应用就处于同一会话中,共享同一远程对象实例。

    如果作用域是application,那么服务器则为每一个 Flex应用创建一个远程的Java对象实例。

    限制远程Java对象可访问方法

    有些时候,远程Java对象定义了许多公共方法,但是我们也许并不 希望这些方法都开放给Flex应用。在这种情况下,可以通过include-methods属性定义允许访问的方法列表,如果Flex应用试图访问该列表 外的方法就会导致异常,在客户端会调用fault事件。

    include-methods属性位于destination节 点的<properties></properties>内。下面的设定只允许Flex客户端访问shoppingCart类的 purchaseItem和deleteItem方法。

        <destination id="shoppingCart">

            <properties>

                <source>com.mark.pojo.shoppingCart</source>

                <scope>session</scope>

                <include-methods>

                    <method name="purchaseItem"/>

                    <method name="deleteItem"/>

                </include-methods>

            </properties>

        </destination>

    如果你只想限制对某几个公共方法的远程访问,使 用<exclude-methods></exclude- methods>属性会更加方便。下面的配置设定了Flex客户端可以访问shoppingCart类中除了purchaseItem方法之外的其 他公共方法。

    <destination id="shoppingCart">

            <properties>

                <source>com.mark.pojo.shoppingCart</source>

                <scope>session</scope>

                <exclude-methods>

                    <method name="purchaseItem"/>

                </exclude-methods>

            </properties>

        </destination>

    19.2.4  客户端:实例化RemoteObject组件对象

    创建RemoteObject组件对象的MXML标签语法如下:

    <mx:RemoteObject id=”remoteObj” destination=”shoppingCart”/>

    id属性指定了RemoteObject组件实例名称,在接下来调 用该服务对象及处理远程服务响应时使用。destination属性指定了要连接的远程服务的目标,该值必须与服务器端remote- config.xml文件中配置的目标id属性相匹配。

    我们也可以使用ActionScript代码来创建 RemoteObject对象:

    var remoteObj:RemoteObject = new RemoteObject();

    remoteObj.destination = "shoppingCart";

    19.2.5  客户端:调用远程Java对象方法

    使用RemoteObject组件最终访问的是远程Java对象公 开的公共方法。调用远程Java对象方法的最简单方式即直接调用方法名:

    remoteObj.methodName(parm1,parm2,…);

    在MXML标签中,我们可以在用户事件中直接使用这种方式调用远程 服务。例如,如下代码实现了当用户点击“购物”按钮时,调用remoteObj.purchase(‘TV’)。(假定我们配置的远程Java对象开放了 公共方法purchase(String product))。

    <mx:RemoteObject id="remoteObj" destination="shoppingCart"/>

    <mx:Button label="购物" click="remoteObj.purchase(‘TV’)"/>

    在本章“服务器端:实现并部署POJO Java类”节中,我们介绍过,远程Java对象应该避免使用保留方法名。然而,如果由于不可避免的原因你不得不这样做,例如你的远程Java对象开发者 是个“disconnect”方法名的偏执狂,那么使用RemoteObject类的getOperation方法可以缓解你的尴尬。

    public function getOperation(name:String):Operation

    例如,远程Java对象开放了公共方法toString(),我们 可以通过如下代码创建Operation对象来调用该方法:

    public var remoteObj:RemoteObject = new RemoteObject();

    remoteObj.destination = "shoppingCart";

    //创建代表toString方法的操作对象

    public var oper:Operation = remoteObj.getOperation("toString");

    //调用该方法

    oper.send();

    19.2.6  客户端:处理响应和异常

    RemoteObject使用异步方式调用远程Java对象。在调 用操作后,Flex应用并不停止执行其他操作来等待响应,而是允许用户继续交互,执行其他操作。当响应返回时,或者抛出异常时,系统调度result事件 或者fault事件来通知应用,以执行事件侦听器方法。也就是说,我们通过侦听RemoteObject组件的result和fault事件处理响应和异 常。这种方式与处理远程HTTP服务和Web服务响应的方式如出一辙。

    当RemoteObject调用远程方法成功时,系统会调度 result事件。开发者可以使用result事件生成的mx.rpc.events.ResultEvent对象访问服务响应数据。

    如下所示,我们为RemoteObject对象实例添加 result事件和fault事件侦听器,并声明侦听器方法。

    ……

    <mx:Script>

        <![CDATA[

            import mx.rpc.events.FaultEvent;

            import mx.rpc.events.ResultEvent;

           

            //RemoteObject对象result事件侦听器方法

            private function roRespondHandler(event:ResultEvent):void{

                //处理远程服务响应   

            }

           

            //RemoteObject对象fault事件侦听器方法

            private function roErrorHandler(event:FaultEvent):void{

                //处理远程服务调用异常   

            }

        ]]>

    </mx:Script>

        <!--实例化远程对象组件-->

        <mx:RemoteObject id="remoteObj" destination="shoppingCart"

            result="roRespondHandler(event)" fault="roErrorHandler(event)"/>

        <!--调用远程对象组件-->

        <mx:Button label="购物" click="remoteObj.purchase()"/>

    ……

    我们可以采用ResultEvent.result属性或远程服务 组件的Operation.lastResult属性两种方式获取返回数据。

    与处理Web服务返回对象类似,对于复杂类型的返回数据,例如数组 或自定义对象,默认情况下,Flex会将数组类型数据封装为mx.collection.ArrayCollection,将自定义对象类型封装为 mx.utils.ObjectProxy。

    如果远程对象调用失败,系统会触发fault事件,开发者可以为该 事件定义侦听器方法,使用fault事件生成的mx.rpc.events.FaultEvent对象处理异常。具体方式可以参见第18章的18.1.6 节“处理异常”(见第425页)。

    19.2.7  使用<mx:operation>处理多个方法

    类似Web服务能够提供多个操作,远程Java对象也可以开放多个 公共方法,供RemoteObject组件调用。我们可以使用operation类或<mx:method>标签,为一个 RemoteObject组件调用多个远程方法。

    使用这种方式还能够为处理不同方法的响应提供更多的选择,我们可以 为每一个方法定义专有的result和fault事件侦听器,而不是仅仅在RemoteObject组件对象上定义统一的侦听器。

    假设我们定义了Java类shoppingCart,开放了公共方 法clearCart()、purchaseItem(String itemName,int quantity)、deleteItem(String itemName)等方法。

    使用mx.rpc.remoting.Operation类

    mx.rpc.remoting.Operation类专门用于为 RemoteObject类指定远程对象的操作。Operation 是服务上的单个方法,可以通过在服务上调用同名函数,即RemoteObject.operationName()的方式,或者在服务上访问作为属性的 Operation 并调用 send() 方法来调用 Operation,比如RemoteObject.operation.send()。

    使用<mx:method>标签

    我们也可以使用<mx:method>标签为 RemoteObject组件定义多个方法。

    <mx:method>标签必须内嵌 在<mx:RemoteObject></mx:RemoteObject>标签对内,通过name属性指定匹配的远程Java 对象方法名称。开发者可以为每个method标签注册result和fault事件侦听器方法,来分别处理远程Java对象不同方法的响应或调用异常。

    在<mx:method></mx:method> 标签对中,可以嵌入<mx:arguments>标签指定传递给远程方法的参数。Flex不要求使用与远程Java对象方法参数名称完全相同 的名字来定义<mx:arguments>标签。但是,当调用多参的远程方法时,必须保证<mx:arguments>标签指定 的参数顺序与远程方法中的参数顺序相匹配。

    <!--实例化远程对象组件-->

    <mx:RemoteObject id="remoteObj" destination="shoppingCart"

        fault="roErrorHandler(event)">

        <mx:method name="clearCart" result="clearROResultHandler(event);"/>

        <mx:method name="deleteItem"

                result="deleteROResultHandler(event);">

            <mx:arguments>

                <item>{comboItem.selectedItem.data}</item>

            </mx:arguments>

        </mx:method>

    <!-—参数顺序必须与purchaseItem(String itemName,int quantity)方法相匹配-->

        <mx:method name="purchaseItem"

                result="purchaseROResultHandler(event);">

            <mx:arguments>

                <item>{comboItem.selectedItem.data}</item>

                <qty>{txtQuantity.text}</qty>

            </mx:arguments>

        </mx:method>

    </mx:RemoteObject>

    由于我们已经在<mx:method>标签中定义了参 数,因此只须要使用无参数的send()方法实现调用。例如:

    <!--调用远程Java对象purchaseItem方法 -->

        <mx:Button label="购物" click="remoteObj.purchaseItem.send()"/>

  • 相关阅读:
    各浏览器都支持的渐变
    ajax get 和 post
    jQuery给input绑定回车事件
    Thinkpad BIOS里的五个选项设置介绍(转)
    对象的比较与排序(一):类型比较和值比较(转)
    C# 压缩Access数据库(转)
    Firefox 删除插件
    Python进制转换(二进制、十进制和十六进制)
    程序在他人电脑上报缺失msvcr100d.dll 处理(转)
    DataGridView实现双缓冲(转)
  • 原文地址:https://www.cnblogs.com/nianshi/p/1746373.html
Copyright © 2020-2023  润新知