zoukankan      html  css  js  c++  java
  • [转]理解WSRF之一 使用WS-ResourceProperties (整理自IBM网站)

    理解 WSRF第1部分-使用 WS-ResourceProperties

     

    本 教程是一个由 4 部分组成的系列文章中的第 1 部分,该系列介绍 WSRF(Web Services Resource Framework)背后的概念。WSRF 是一组规范,提供一种标准方式,在 Web 服务应用程序的本质上“无状态的”环境中与“有状态”资源交互。这种有状态资源实际上可以是任何东西,从数据库到电子鼠标都是有状态资源。实际上,可以使 用 WSRF 来处理任何可以通过改变其属性来操纵的东西。

    WS-Resource 是一个有状态资源(比如数据库或硬盘)和它与之交互的 Web 服务的组合。本教程解释了创建 WS-Resources、请求和更新用于定义 WS-Resource 状态的属性。我们将介绍以下内容:

    1.       WSRF 规范的概述。

    2.       本系列教程中使用的系统的概述。

    3.       关于 WSDL 的基本信息。

    4.       关于的 WS-Addressing 的基本信息,WS-Addressing 用于定位 WS-Resource。

    5.       创建 WS-Resource。

    6.       获得和设置 WS-Resource 属性。

    注意,WSRF 作为一种规范,定义了描述这些操作的 WSDL 文件的结构。该 WSDL 文件然后可以被任何语言的实现所使用。本教程描述 WSDL 文件的创建并展示产生的 SOAP 消息。

    一定要明白,WSRF 规范只定义应该做什么,而不定义应该如何做。这里描述的概念的实际实现留给了应用程序去完成。在本系列的第 4 部分中,我们将使用 Globus Alliance 提供的 Core Java WSRF 类来讨论该实现。

    在本系列中,我们将使用一系列围绕地球的人造卫星作为例子。我们将创建一个 WS-Resource,它就代表这样一个人造卫星。然后我们将请求它的属性以检索它的数据,更改它的属性以将它发射到天空中,并更改它观测的对象。

    l         网格计算简介

    首先,我们指出 WSRF 的应用远远超出了网格,但是 WSRF 是在网格中开发的,所以网格是 WSRF 可以做什么的一个很好的例子。之后,将花点时间为那些不熟悉网格的人解释一下网格是什么。

    数 百万的 Web 用户已经体验了网格计算,只是大多数人都没有感觉到而已。1998 年,由于 NASA 发起了一个新计划,使得 Search for Extraterrestrial Intelligence (SETI) 项目差点夭折,此时就创建了也许是最著名的网格计算项目。他们的 Aricebo 无线电望远镜得到非常大量的数据,但是没有足够的处理能力可以处理这些数据。为了解决这个问题,他们创建了一个 screensaver,当计算机不忙时,它会从中央服务器请求一包数据并进行分析,然后把结果发送回去。然后又请求一包新的数据,并重复刚才的步骤。数 百万用户下载了 screensaver 并参与该项目。

    大型网格应用程序更加复杂,要处理的问题也更多,这些问题与身份验证、跨组织边界的进程间通信和高性能数据传输等方面有关。尽管网格狂热者可能不愿意听到 SETI@Home 的情况,但是它确实提供了网格工作原理的一个很好的例子。它涉及以下步骤:

    工作被分成适合于在多个系统上处理的“单元”。该“工作”可以是计算、存储或其他类型的处理。

    单元被分布到多个客户机。这个步骤通过让客户机请求或“pull”工作,或者让中央服务器将工作“push”给可用的客户机来完成。

    总体进展、需求和状态由中央系统或系统组维护。

    当前的网格应用程序一般遵循这种模式,有一个中央系统与客户机交互,这些客户机位于那些一般在地理位置上与中央服务器分离的系统上。

    l         使用 Web 服务:承诺和问题

    既然多个客户机在不同的地方,那么 Web 服务应该是网格计算顺理成章的选择。毕竟,它提供一种标准而容易的方法,以从一个系统到另一个系统获得信息,而不用求助于特定于平台或语言的方法,比如 CORBA、DCOM 或 Java-RMI。

    但是,原来并不是这样的。早期的网格应用程序使用其他更加不可移植的方法。但是为什么呢?

    也 许最贴切的是体系结构方面的原因。尽管网格应用程序可以在很多机器上实现,但它仍然是一个应用程序,因此很难与本质上是无状态的体系结构相协调。当使用数 据库客户机连接到一个数据库时,您就保持了连接,并且可以插入记录,然后再查看插入的结果。另一个客户查看表时不会看到该记录,除非您提交了事务,但是数 据库认识您的会话,并知道是您。

    Web 服 务的工作方式不是这样的。利用 Web 服务,您发出请求(比如插入一条记录)并得到响应(比如插入成功),然后断开连接。没有正在进行的会话需要管理。例如 HTTP —— 在大多数情况下,Web 服务通过 HTTP 传输 —— 每个请求独立于前一个请求,Web 服务没有访问或使用任何不是当前输入消息一部分的信息。

    WSRF 的目标是通过创建“状态”概念以及处理状态的方法来解决该问题。

    l         有状态资源

    那么到底什么是“状态”,什么又是“有状态”资源呢?

    有状态资源是一些即使您不与之交互也存在的东西。例如数据库,即使在您不查询它的时候,它也存在。围绕行星的人造卫星即使在您不与之对话时也存在。甚至简单的计数器,在调用之间,或者每次调用它返回一个 1 时,都必须存在。

    此 外,一定要明白,状态概念也包含属性的思想。当要求您把所借的东西以原状态返还时,涉及某些属性的值,比如清洁度、修理要求、油罐中的汽油量,等等。有状 态资源与此类似,具有定义其状态的属性,并且这些属性就是我们将与资源交互的方式,如 WS-Resource 的属性 中所示。

    l         Web 服务 + 有状态资源 = WS-Resource

    根据规范可知,WS-Resource 是 Web 服务与它在其上起作用的有状态资源的组合。但是这真正的含义是什么呢?

    让我们从实际的角度来看这个问题。假设我们有一个系统,涉及到管理一组人造卫星。每个人造卫星是一个有状态资源,因为即使在我们不与之对话时它也存在。我们还有一个 Web 服务,它提供人造卫星功能,比如更改反向、检索信息,或者甚至调整姿势。

    通 过将者二者组合起来,我们创建了一个 WS-Resource。注意,并不需要一对一的对应关系。例如,这个 Web 服务可以与几个不同的人造卫星交互,从而创建几个引用相同服务的不同 WS-Resources。另一方面,一个人造卫星可以与几个不同的服务(比如控制宇宙实验的服务和发射激光束的服务)交互,从而创建几个引用相同有状态 资源的不同 WS-Resources。

    为了使用 WS-Resource,必须了解它的属性。

    l         WS-Resource 的属性

    正如 有状态资源 中所提到的,有状态资源(以及 WS-Resource)具有各种与之相关的属性。例如,人造卫星可能具有以下属性:

    latitude

    longitude

    altitude

    pitch

    yaw

    roll

    focalLength

    currentView

    在 本例中,latitude、longitude 和 altitude 这前三个属性指定人造卫星的位置。其次,pitch、 yaw 和 roll 指定它的方位,或者说它看起来的方向。最后两个属性,focalLength 和 currentView,指定它离观测点的距离以及它在这一点所看到的东西。

    这 些属性的值定义资源的状态。更改属性值,就更改了状态。事实上,我们就是这样来控制人造卫星的。要更改它的位置,我们就改变它的一个位置属性。要更改它的 方位,我们就改变它的一个方位属性。实际上,我们想要对该人造卫星做任何事情(在这个非常有限的实现中),我们都只要改变这些属性就可以了。

    但是如何来做到 这一点?

    l         进入 WSRF

    好了,既然 WS-Resource 是有状态资源和 Web 服务的组合,并且我们通过请求和设置它的属性来操纵它,那么如何来做到这一点呢?

    有很多方法来做到这一点,但是问题也正在于此。需要的是一种做出请求的标准方式,以获取和设置各个属性。

    进 入 WSRF。WSRF 实际上是一系列规范,用于定义标准的“消息模式”或方法,以请求属性的值或者指定这些属性应该变更。实际上,WSRF 定义一些标准方法,以处理关于处理 WS-Resources 的各个方面,比如处理它们的属性,从而将它们成组在一起,以达到诸如这样的目的 —— 进行身份验证,确保它们被及时地销毁。

    WSRF 定 义这些操作的方法是,指定它们应该如何出现在 Web 服务描述语言(Web Services Description Language,WSDL)文件中。WSDL 文件定义 Web 服务会话两端之间传输的消息,所以通过定义 WSDL 文件,WSRF 定义了发生的任何交互的形式。

    当我们说到“WSRF”时,实际上是指几个不同的规范:

    1.       WS-ResourceProperties (WSRF-RP)指定 ResourceProperties 在 WSDL 文件中被定义的形式。它还指定消息的形式,这些消息用于请求和接收属性的值,还解释了如何更改、添加和删除 WS-Resource 的属性。

    2.       WS-ResourceLifetime (WSRF-RL)谈论这样一些状态,即 WS-Resource 需要过期了,或者在它不再需要了时应该被显式地销毁。

    3.       WS-ServiceGroup (WSRF-SG)定义创建一组 Web 服务(比如可用服务的注册表)的方法。

    4.       WS-Base Faults (WSRF-BF)定义一种标准的方法,用于指出基于 WSRF 的应用程序中的错误。

    您将注意到,没有哪一个规范简单地描述了所有这一切应该如何一起工作。这项工作(几乎)是由 Modeling Stateful Resources with Web Services 白皮书完成的,该书解释了一般的概念,并将它们联系在一起。

    本 教程除了介绍白皮书中的一些概念之外,还将讨论 WS-ResourceProperties 规范。本系列的以后各期将讨论其他的 WSRF 规范,以及 Web Services Notifications (WSN) 规范(整个 WSRF 中都引用了这些规范)。

    l         什么是 WSDL,为什么我要关注它?

    在正式开始在 WSDL 文件中创建 WS-Resources 之前,我们首先花点时间来看一下 WSDL 文件的目的和结构。这些描述就是在 WSDL 文件中。

    Web 服 务 —— 或者至少是与 WS-Resources 相关的 Web 服务 —— 由 SOAP 消息组成。SOAP 消息具有一个标准的“信封”,其中包含一个“有效负载”。该有效负载是由服务器(在请求时)和客户机(在响应时)分析的数据。考虑下面这个 SOAP 消息:

    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">

        <SOAP-ENV:Header/>

        <SOAP-ENV:Body>

            <SetAltitudeRequest xmlns="http://example.com/satellite.xsd">

                <altitude>47700</altitude>

            </SetAltitudeRequest>

        </SOAP-ENV:Body>

    </SOAP-ENV:Envelope>

    它包含标准信封和有效负载,前者在 http://schemas.xmlsoap.org/soap/envelope/ 名称空间(SOAP-ENV)中,后者在 http://example.com/satellite.xsd 名称空间中。

    有 效负载可以是任何东西,因此存在这样一个问题:如何定义应用程序期望看到什么,以及返回什么?因而有了 WSDL 文件的用武之地。最终,我们将使用一个 WSDL 文件来定义 WS-Resource 所使用的“消息模式”,但是在本节,我们只来看 WSDL 文件的各部分是如何组合在一起的。

    l         消息和类型

    我们首先定义一条我们将会发送的实际消息:

    <?xml version="1.0"?>

    <definitions name="Satellite"

        targetNamespace="http://example.com/satellite.wsdl"

        xmlns:tns="http://example.com/satellite.wsdl"

        xmlns:satTypes="http://example.com/satellite.xsd"

        xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"

        xmlns="http://schemas.xmlsoap.org/wsdl/">

        <types>

            <schema targetNamespace="http://example.com/satellite.xsd"

                  xmlns="http://www.w3.org/2000/10/XMLSchema">

               <element name="SetAltitudeRequest">

                  <complexType>

                      <all>

                          <element name="altitude" type="float"/>

                      </all>

                  </complexType>

               </element>

               <element name="SetAltitudeResponse">

                  <complexType>

                      <all>

                          <element name="result" type="string"/>

                      </all>

                  </complexType>

               </element>

           </schema>

        </types>

        <message name="SetAltitudeInput">

            <part name="body" element="satTypes:SetAltitudeRequest"/>

        </message>

        <message name="SetAltitudeOutput">

            <part name="body" element="satTypes:SetAltitudeResponse"/>

        </message>

    </definitions>

    从 底部开始,我们定义了两种类型的消息。第一种是 SetAltitudeInput,这是我们将发送给服务器作为输入的消息。它是您在什么是 WSDL,为什么我要关注它? 中看到的 SOAP 消息中的消息。第二种消息是 SetAltitudeOutput,这是服务器发送给客户机的响应。两种消息都指定一个元素,消息体将放在该元素中。

    这些元素的实际定义位于文件顶部的模式(schema)中。例如,SetAltitudeInput 消息包含一个 SetAltitudeRequest 元素,该元素自己又包含一个 altitude 元素,后面这个元素的内容必须是一个 float。

    接下来,我们将组合这些消息,以创建服务器执行的一个操作。

    l         端口类型和操作

    既然知道了我们将要发送的消息是什么,现在就需要指定它们将要完成的角色。要做到这一点,我们将创建一个 portType 及其相关的 operation:

    ...

        <message name="SetAltitudeInput">

            <part name="body" element="satTypes:SetAltitudeRequest"/>

        </message>

        <message name="SetAltitudeOutput">

            <part name="body" element="satTypes:SetAltitudeResponse"/>

        </message>

        <portType name="AltitudePortType">

            <operation name="SetAltitude">

               <input message="tns:SetAltitudeInput"

                      wsa:Action="http://example.com/SetAltitude" />

               <output message="tns:SetAltitudeOutput"

                      wsa:Action="http://example.com/SetAltitudeResponse" />

            </operation>

        </portType>

    </definitions>

    这 里,我们定义了一个 portType 叫做 AltitudePortType,以及它的一个 operation 叫做 SetAltitude。我们实际上可以在该 portType 中定义任意数量的操作,但是现在我们是为了保持简单。SetAltitude 操作指定一个 input 消息 SetAltitudeInput 和一个 output 消息 SetAltitudeOutput。(下一节我们将处理 wsa:Action 属性。此外,请注意名称空间信息。)

    您也可以指定一个 fault 消息在有问题时发送,在本教程系列的后面将会介绍这一点,但是现在还是保持简单。

    l         服务和绑定

    至此,我们已经使用 portType 定义了可以做什么 事情,但是没有定义如何 做。要完成这个过程,我们需要创建一个描述如何做的 binding,并将它附加到实际的 service:

    ...

        <portType name="AltitudePortType">

            <operation name="SetAltitude">

               <input message="tns:SetAltitudeInput"

                      wsa:Action="http://example.com/SetAltitude" />

               <output message="tns:SetAltitudeOutput"

                      wsa:Action="http://example.com/SetAltitudeResponse" />

            </operation>

        </portType>

        <binding name="AltitudeSoapBinding" type="tns:AltitudePortType">

            <soap:binding style="document"

                      transport="http://schemas.xmlsoap.org/soap/http"/>

            <operation name="SetAltitude">

               <input>

                   <soap:body use="literal"/>

               </input>

               <output>

                   <soap:body use="literal"/>

               </output>

            </operation>

        </binding>

        <service name="SatelliteService">

            <port name="AltitudePort" binding="tns:AltitudeSoapBinding">

                <soap:address location="http://example.com/satellite"/>

            </port>

        </service>

    </definitions>

    我们还是从底部开始,先看 service 元素。一个 WSDL 文件可以定义多个服务。例如,您可能有用于不同目的的不同服务,或者在不同位置有具有相同目的的不同服务,或者具有不同绑定的不同服务,比如一个用于 SOAP 的服务和一个用于 SMTP 的服务。

    在 本例中,我们将利用一个端口 AltitudePort 来定义一个服务 SatelliteService。但是我们知道关于该端口的哪些情况呢?哦,我们知道 SOAP 请求应该发送到 http://example.com/satellite。我们还知道,为了获得关于如何发送消息的更多信息,应该检查 AltitudeSoapBinding。

    AltitudeSoapBinding 指定它是 AltitudePortType 的一个实现,所以我们知道发送什么消息。binding 本身指定每个操作中的消息是如何格式化的。在本例中,我们使用“document/literal”样式,这意味着我们只是将定义好的元素拖放到 Body 中。

    我们知道了消息将发送到哪里,如何格式化这些消息,以及这些消息应该是什么。到 创建 WS-Resource 一节,我们将介绍如何创建 WSRF 定义的特定消息,但是首先我们需要了解一下 WS-Addressing。

    l         什么是 WS-Addressing,为什么我要关注它?

    以 前,很容易指定 Web 服务的地址。所有您真正需要的就是 URL,所有其他信息都包含在 SoapAction 头部或消息本身中。现在,Web 服务应用程序变得越来越复杂,并不总是那么简单。您若想要让应答发送到除最初的请求者之外的其他地方,或者需要其他信息(比如会话标识符)来定义实际的 “位置”,那该怎么办?

    或者您只是需要附加到 Web 服务的一个特定实例,那该怎么办?我们在 WS-Resources 的情况中将会遇到这个问题,所以我们需要一种处理它的方式。

    WS-Addressing 提 供一种方式来指定关于位置的信息,而不只是一个统一资源标识符(Universal Resource Identifier,URI)或 URL。实际上,在我们的例子中,它提供一种标准的方式,将大量的信息添加到 SOAP 消息。我们来构造一个 SOAP 消息,比如:

    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

    xmlns:wsa="http://www.w3.org/2005/02/addressing"

    xmlns:sat="http://example.org/satelliteSystem">

        <SOAP-ENV:Header>

          <wsa:To SOAP-ENV:mustUnderstand="1">http://example.com/satellite</wsa:To>

          <wsa:Action>http://example.com/SetAltitude</wsa:Action>

          <sat:SatelliteId>SAT9928</sat:SatelliteId>

        </SOAP-ENV:Header>

        <SOAP-ENV:Body>

            <SetAltitudeRequest xmlns="http://example.com/satellite.xsd">

                <altitude>47700</altitude>

            </SetAltitudeRequest>

        </SOAP-ENV:Body>

    </SOAP-ENV:Envelope>

    在实际的 SOAP 消息中具有该信息似乎并不重要,但是请记住,消息可能会传输通过多个系统,甚至需要多次传输才能到达最终目的地。

    要指定该信息,我们需要创建一个 EndpointReference。

    WS-Addressing 引入了 EndpointReference 概念。EndpointReference 是一种方式,用于指定让消息到达适当的位置并带有适当的相关信息所需的信息。例如,我们在前一屏中指定的消息的 EndpointReference 应该是:

    <wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/02/addressing"

    xmlns:sat="http://example.org/satelliteSystem">

        <wsa:Address>http://example.com/satellite</wsa:Address>

        <wsa:ReferenceProperties>

             <sat:SatelliteId>SAT9928</sat:SatelliteId>

        </wsa:ReferenceProperties>

    </wsa:EndpointReference>

    理 解 EndpointReference 和 SOAP 消息之间的关系很重要,因为 EndpointReference 就是我们指定特定 WS-Resource 的位置的方式。例如,当我们请求创建新的 WS-Resource 时,响应将包含一个指向它的 EndpointReference。

    l         什么是 WS-Resource?

    至此,您应该在概念上对什么是 WS-Resource 有了很好的理解,并且应该对 WSDL 和 WS-Addressing 有了很好的基本了解。现在开始实际地创建和使用 WS-Resources。

    我们首先来定义 WS-Resource 到底真正是什么。在我们的人造卫星例子中,我们可以具有几种类型的 WS-Resources,比如:

    一个服务,用于设置或检索特定人造卫星的高度。

    一个服务,用于设置或检索特定人造卫星的位置或方位。

    一个服务,用于提供对一个进程的访问,该进程计数特定人造卫星观测到的恒星。

    关于该列表有两件事情一定要注意:即所有三个 WS-Resources 都可以引用相同的人造卫星,还有,WS-Resource 是由服务和有状态资源(在本例中是人造卫星)的组合定义的,而不是由它可以执行的操作数量定义的。

    现 在,我们可以说 WS-Resource 是 Web 服务和有状态资源的组合,但是我们如何在应用程序中表示这个有状态资源呢?答案就在它的 ResouceProperties 中。正如 有状态资源 中提到的,对象的状态可以由它的各种属性的值来决定。因为我们真正感兴趣的就是对象的状态,所以我们可以把有状态资源表示为一个展示其属性的 XML 文档。该文档叫做资源属性文档。在我们的人造卫星例子中,它可能是具有以下代码行的文档:

    <satProp:GenericSatelliteProperties  xmlns:satProp="http://example.com/satellite">

       <satProp:latitude>30.3</satProp:latitude>

       <satProp:longitude>223.2</satProp:latitude>

       <satProp:altitude>47700</satProp:altitude>

       <satProp:pitch>49</satProp:pitch>

       <satProp:yaw>0</satProp:yaw>

       <satProp:roll>32</satProp:roll>

       <satProp:focalLength>21999992</satProp:focalLength>

       <satProp:currentView>

            http://example.com/satellite/2239992333.zip

       </satProp:currentView>

    </satProp:GenericSatelliteProperties>

    状态的更改需要一个或多个这些属性的更改,反之亦然。

    就像可以通过添加成员或方法来扩展类一样,我么可以通过添加属性来扩展 WS-Resource。例如,考虑这样一种情形,我们具有一个人造卫星,它也充当恒星计数器。除了有状态资源的一般属性之外,我们可能还有一个 currentCount 属性:

    <satProp:GenericSatelliteProperties

           xmlns:satProp="http://example.com/satellite"

           xmlns:counterProp="http://example.com/satellite/CounterSatelliteProperties">

       <satProp:latitude>30.3</satProp:latitude>

       <satProp:longitude>223.2</satProp:latitude>

       <satProp:altitude>47700</satProp:altitude>

       <satProp:pitch>49</satProp:pitch>

       <satProp:yaw>0</satProp:yaw>

       <satProp:roll>32</satProp:roll>

       <satProp:focalLength>21999992</satProp:focalLength>

       <satProp:currentView>

            http://example.com/satellite/2239992333.zip

       </satProp:currentView>

       <counterProp:currentCount>92828</counterProp:currentCount>

    </satProp:GenericSatelliteProperties>

    注意新信息是在一个独立的名称空间中。

    l         合并 WS- 和 Resource:WSDL 文件

    至此,我们已经创建了有状态资源(人造卫星)的表示,但是要真正地创建 WS-Resource,我们还必须使用 WSDL 文件将它绑定到服务。

    我们首先来看一个基本的 WSDL 文件:

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

    <definitions name="Satellite"

        targetNamespace="http://example.com/satellite"

        xmlns="http://schemas.xmlsoap.org/wsdl/"

        xmlns:tns="http://example.com/satellite"

        xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"

        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

        xmlns:wsrp=

    "http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.xsd"

        xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

            <wsdl:import namespace=

    "http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.wsdl"

           location="WS-ResourceProperties.wsdl" />

            <types>

              <xsd:schema targetNamespace="http://example.com/satellite"

                          xmlns:xsd="http://www.w3.org/2001/XMLSchema">

                            <xsd:import namespace=

     "http://schemas.xmlsoap.org/ws/2004/03/addressing"

                               schemaLocation="WS-Addressing.xsd" />

              </xsd:schema>

            </types>

    </definitions>

    该 文件现在还很空,但是请注意,为了能够工作,还需要导入两个文件。WS-ResourceProperties.wsdl 和 WS-Addressing.xsd 文件的典型版本可能会引用您还没创建在机器上的目录,所以为了简单起见,您可以从教程参考资料 下载简化的版本。

    既然有了框架,现在我们就来填充它吧。

    首先,我们将实际的有状态资源添加到文件,并将之与 Web 服务关联:

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

    <definitions name="Satellite"

        targetNamespace="http://example.com/satellite"

        xmlns="http://schemas.xmlsoap.org/wsdl/"

        xmlns:tns="http://example.com/satellite"

        xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"

        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

        xmlns:wsrp=

    "http://docs.oasis-open.org/wsrf/2004/06/wsrf-

    WS-ResourceProperties-1.2-draft-01.xsd"

        xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

            <wsdl:import namespace=

    "http://docs.oasis-open.org/wsrf/2004/06/wsrf-

    WS-ResourceProperties-1.2-draft-01.wsdl"

              location="WS-ResourceProperties.wsdl" />

          <types>

          <xsd:schema targetNamespace="http://example.com/satellite"

              xmlns:xsd="http://www.w3.org/2001/XMLSchema">

         

              <xsd:import namespace=

                      "http://schemas.xmlsoap.org/ws/2004/03/addressing"

                      schemaLocation="WS-Addressing.xsd" />

               

              <xsd:element name="latitude" type="xsd:float" />

              <xsd:element name="longitude" type="xsd:float" />

              <xsd:element name="altitude" type="xsd:float" />

              <xsd:element name="pitch" type="xsd:float" />

              <xsd:element name="yaw" type="xsd:float" />

              <xsd:element name="roll" type="xsd:float" />

              <xsd:element name="focalLength" type="xsd:float" />

              <xsd:element name="currentView" type="xsd:string" />

               

              <xsd:element name="GenericSatelliteProperties">

                <xsd:complexType>

                   <xsd:sequence>

                     <xsd:element ref="latitude" minOccurs="1"

                     maxOccurs="1"/>

                     <xsd:element ref="longitude" minOccurs="1"

                     maxOccurs="1"/>

                     <xsd:element ref="altitude" minOccurs="1"

                     maxOccurs="1"/>

                     <xsd:element ref="pitch" minOccurs="1"

                     maxOccurs="1"/>

                     <xsd:element ref="yaw" minOccurs="1"

                     maxOccurs="1"/>

                     <xsd:element ref="roll" minOccurs="1"

                     maxOccurs="1"/>

                    <xsd:element ref="focalLength" minOccurs="1"

                     maxOccurs="1"/>

                     <xsd:element ref="currentView" minOccurs="1"

                     maxOccurs="1"/>

                   </xsd:sequence>

                </xsd:complexType>

              </xsd:element>             

               

          </xsd:schema>

           

        </types>

        <portType name="SatellitePortType"

                wsrp:ResourceProperties=

                "tns:GenericSatelliteProperties">

        </portType>

       

        <binding name="SatelliteSoapBinding"

        type="tns:SatellitePortType">

          <soap:binding style="document"

          transport="http://schemas.xmlsoap.org/soap/http"/>

        </binding>

       

        <service name="SatelliteService">

            <port name="SatellitePort"

            binding="tns:SatelliteSoapBinding">

                <soap:address location=

                "http://example.com/satellite"/>

            </port>

        </service>

    </definitions>

    我 们首先是添加 Web 服务的基础、实际的 service 元素和将之与 portType 关联的 binding。portType 本身还没有任何操作,但是重要的部分是 wsrp:ResourceProperties 属性。该属性指定,Web 服务执行的任何操作都是在一个特定类型的有状态资源上执行的,如 GenericSatelliteProperties 元素所定义的。GenericSatelliteProperties 元素定义在 schema 中。该有状态资源和该 Web 服务的组合就是 WS-Resource。

    注意,规范中指出,在创建资源属性文档(比如本例中的 GenericSatelliteProperties)时,必须 使用这里展示的样式,即初始元素是定义和引用的,而不是内联地定义的。

    现在我们向 WSDL 文件添加一些实际的操作,看它是如何工作的。

    l         请求新的人造卫星

    当然,该练习的整个目的是真正对 WS-Resource 做一些事情,所以我们要做的第一件事情是,创建对实际 WS-Resource 实例的一个引用:

    ...

        <types>

           <xsd:schema targetNamespace="http://example.com/satellite"

               xmlns:xsd="http://www.w3.org/2001/XMLSchema">

               

                <xsd:import namespace=

                   "http://schemas.xmlsoap.org/ws/2004/03/addressing"

                      schemaLocation="WS-Addressing.xsd" />

               

              <xsd:element name="createSatellite">

                  <xsd:complexType/>

              </xsd:element>

               

              <xsd:element name="createSatelliteResponse">

                 <xsd:complexType>

                     <xsd:sequence>

                         <xsd:element ref="wsa:EndpointReference"/>

                      </xsd:sequence>

                  </xsd:complexType>

              </xsd:element>

               

              <xsd:element name="GenericSatelliteProperties">

                   ...

              </xsd:element>           

               

            </xsd:schema>

           

        </types>

        <message name="CreateSatelliteRequest">

          <part name="request" element="tns:createSatellite"/>

        </message>

       

        <message name="CreateSatelliteResponse">

         <part name="response" element=

         "tns:createSatelliteResponse"/>

        </message>

       

        <portType name="SatellitePortType"

          wsrp:ResourceProperties=

          "tns:GenericSatelliteProperties">

          <operation name="createSatellite">

              <input message="tns:CreateSatelliteRequest"

                   wsa:Action=

                   "http://example.com/CreateSatellite" />

               <output message="tns:CreateSatelliteResponse"

                  wsa:Action=

                  "http://example.com/CreateSatelliteResponse" />

            </operation>

        </portType>

       

       <binding name="SatelliteSoapBinding" type=

       "tns:SatellitePortType">

        <soap:binding style="document" transport=

        "http://schemas.xmlsoap.org/soap/http"/>

          <operation name="createSatellite">

              <input>

                  <soap:body use="literal"/>

               </input>

               <output>

                  <soap:body use="literal"/>

               </output>

         </operation>

       </binding>

       

       <service name="SatelliteService">

          <port name="SatellitePort" binding=

          "tns:SatelliteSoapBinding">

              <soap:address location=

              "http://example.com/satellite"/>

           </port>

       </service>

    </definitions>

    乍 一看,这与我们在 需要了解的 WSDL 知识 中创建的 WSDL 文件没有太大的区别。我们具有一个指向 binding 的 service,binding 解释如何实现 portType。portType 定义一个操作,即 createSatellite,该操作使用一个 input 和一个 output 消息。这两个消息定义在 schema 中。

    这个文件有一点稍微与最初的文件不同:不是返回一个简单的值,服务是返回一个指向新创建的 WS-Resource 的 EndpointReference。我们来看这在 SOAP 消息中是如何实现的。

    l         SOAP 请求

    关于创建 WS-Resource 的实际 SOAP 请求是非常简单的:

    <SOAP-ENV:Envelope  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">

        <SOAP-ENV:Header/>

        <SOAP-ENV:Body>

            <createSatellite xmlns="http://example.com/satellite"/>

        </SOAP-ENV:Body>

    </SOAP-ENV:Envelope>

    我们还没有实际的对象,所以该请求到达 WSDL 文件中列出的 URI,并且我们将该请求定义为一个简单的 createSatellite 元素。

    响应要稍微有意思一些。

    l         SOAP 响应

    一旦您发送针对新人造卫星的请求,服务器就创建一个对新 WS-Resource 的引用,并以 EndpointReference 形式将它返回:

    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">

        <SOAP-ENV:Header/>

        <SOAP-ENV:Body>

           <wsa:EndpointReference

           xmlns:wsa="http://www.w3.org/2005/02/addressing"

                 xmlns:sat="http://example.org/satelliteSystem">

               <wsa:Address>http://example.com/satellite</wsa:Address>

               <wsa:ReferenceProperties>

                   <sat:SatelliteId>SAT9928</sat:SatelliteId>

               </wsa:ReferenceProperties>

           </wsa:EndpointReference>

        </SOAP-ENV:Body>

    </SOAP-ENV:Envelope>

    注意,EndpointReference 的 Address 元素指向我们在 WSDL 文件中列出的同一 URI,所以信息仍然到达相同的地方,只是量的增多。

    现 在我们应该注意,这不是一个普通的端点引用。 ReferenceProperties 元素展示一个标识符,该标识符最终将用于识别 WS-Resource,所以这实际上是一个 WS-Resource 限定的端点引用。正如您马上就会看到的,我们可以使用该信息来对 WS-Resource 做出后续调用。

    l         我们想要完成什么?

    好的,已经创建了 WS-Resource,那么我们可以对它做什么呢?

    实 际上,可以通过调整它的属性来做任何事情。例如,可以通过更改 altitude 属性来改变人造卫星轨道的大小。不,只是更改值并不能移动人造卫星;人造卫星的实际移动是由 Web 服务背后的应用程序决定的。但是这是 WS-Resources 所真正关心的:创建一种方式,以便通过更改属性来操纵对象。规范只是指出了如何将这些更改告诉 Web 服务。它不关心应用程序是如何真正操纵对象的,我们也不关心。

    但 是在真正开始更改属性之前,我们先来看看属性。在本节中,首先来看我们在 创建 WS-Resource 中创建的人造卫星 WS-Resource 的 altitude 属性。然后将讲述一次性请求所有的 orientation 值。然后再介绍使用 XPath 来查询多个值。

    l         请求属性

    请求属性的值是构造适当 SOAP 消息过程中的一个简单过程。例如,假设我们想要请求 altitude 属性的值。基本的 SOAP 消息可能看起来像下面这样:

    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

        xmlns:wsrp=

    "http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-

    ResourceProperties-1.2-draft-01.xsd">

     <SOAP-ENV:Header>...</SOAP-ENV:Header>

     <SOAP-ENV:Body>

         <wsrp:GetResourceProperty xmlns:satProp=

         "http://example.com/satellite">

            satProp:altitude

         </wsrp:GetResourceProperty>

     </SOAP-ENV:Body>

    </SOAP-ENV:Envelope>

    wsrp:GetResourceProperty 元素是 WS-ResourceProperties 规范的一部分。我们甚至不必在 WSDL 文件中定义它。它给我们这样一个地方,可以指定我们想要获得值的属性。

    但是,SOAP 消息还没有真正完成。是的,它是一个 SOAP 消息,但是如果我们像这样把它发送给 Web 服务,服务将不知道我们引用的是哪个 WS-Resource。接下来我们将关心这个问题。

    l         完全的 SOAP 请求

    在前一屏,即 请求属性 中,我们创建了一个 SOAP 消息,它指定了我们想要检索的属性,但是为哪个 WS-Resource 创建的呢?

    当创建人造卫星时,Web 服务返回一个指向新创建的 WS-Resource 的端点引用。我们可以将该信息添加到 SOAP 消息的 Header,像下面这样:

    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

           xmlns:sat="http://example.org/satelliteSystem"

           xmlns:wsa="http://www.w3.org/2005/02/addressing"

           xmlns:wsrp="http://docs.oasis-open.org/wsrf/2004/06/wsrf-

           WS-ResourceProperties-1.2-draft-01.xsd">

        <SOAP-ENV:Header>

           <wsa:Action>

    http://docs.oasis-open.org/wsrf/2004/06/WS-ResourceProperties/GetResourceProperty

           </wsa:Action>

           <wsa:To SOAP-ENV:mustUnderstand="1">

                http://example.com/satellite

           </wsa:To>

           <sat:SatelliteId>SAT9928</sat:SatelliteId>

        </SOAP-ENV:Header>

        <SOAP-ENV:Body>

           <wsrp:GetResourceProperty

           xmlns:satProp="http://example.com/satellite">

              satProp:altitude

           </wsrp:GetResourceProperty>

        </SOAP-ENV:Body>

    </SOAP-ENV:Envelope>

    wsa:Action 元 素不是初始端点引用的一部分;它随我们想要做的事情而变化。在本例中,我们使用 GetResourceProperty 操作。wsa:To 元素从端点引用中的 wsa:Address 获得值,而任何 wsa:ReferenceProperty 值都直接包含在 Header 中。

    您 会注意到,我们没有讨论 SatelliteId 值。这是故意的。包含在端点引用中的任何用于识别特定 WS-Resource 的信息都必须被应用程序忽略,只是在发送消息时要传送它。根据规范,即使尝试去解释值也认为是不适当的。这意味着被传输为一个“黑盒”,导致一种未经检查 的生活。

    l         接收 ResourceProperty

    一旦请求属性,就需要获得返回值,并且 WS-ResourceProperties 规范也定义了这种消息的形式。在我们的例子中,我们将接收这样一个消息:

    <SOAP-ENV:Envelope xmlns:SOAP-ENV=

    "http://schemas.xmlsoap.org/soap/envelope/"

         xmlns:sat="http://example.org/satelliteSystem"

         xmlns:wsa="http://www.w3.org/2005/02/addressing"

         xmlns:wsrp=

    "http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-

    ResourceProperties-1.2-draft-01.xsd">

     <SOAP-ENV:Header>

           <wsa:Action>

    http://docs.oasis-open.org/wsrf/2004/06/WS-

    ResourceProperties/GetResourcePropertyResponse

           </wsa:Action>

           <wsa:To SOAP-ENV:mustUnderstand="1">

                http://example.com/myClient

           </wsa:To>

        </SOAP-ENV:Header>

        <SOAP-ENV:Body>

           <wsrp:GetResourcePropertyResponse

                 xmlns:satProp=

                 "http://example.com/satellite">

              <satProp:altitude>

              47700

              </satProp:altitude>

           </wsrp:GetResourcePropertyResponse>

        </SOAP-ENV:Body>

    </SOAP-ENV:Envelope>

    在 本例中,Header 信息并不引用服务,而是引用客户机; http://example.com/myClient 是应该接收响应的客户机的 URI。在大多数情况下,这与发出请求的客户机是相同的,但是您也可以使用 wsa:Reply-To 元素将响应发送到别的地方。

    在实际的消息体中还有一个标准元素 wsrp:GetResourcePropertyResponse,但是在本例中,它包含请求的实际属性,以及它的当前值。

    现在来看这在 WSDL 文件中是什么样的。

    l         WSDL 文件

    为了将这些功能添加到应用程序,我们需要将它们添加到 WSDL 文件,但是因为我们使用已经定义好的标准消息交换模式,所以我们只需要添加一个新操作,像下面这样:

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

    <definitions name="Satellite"

        targetNamespace="http://example.com/satellite"

        xmlns="http://schemas.xmlsoap.org/wsdl/"

        xmlns:tns="http://example.com/satellite"

        xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"

        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

        xmlns:wsrp="http://docs.oasis-open.org/wsrf/2004/06/

        wsrf-WS-ResourceProperties-1.2-draft-01.xsd"

        xmlns:wsrpwsdl=

        "http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-

        ResourceProperties-1.2-draft-01.wsdl"

        xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

       

        <wsdl:import namespace=

    "http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.wsdl"

                  location="WS-ResourceProperties.wsdl" />

       

     <types>

          <xsd:schema targetNamespace="http://example.com/satellite"

              xmlns:xsd="http://www.w3.org/2001/XMLSchema">

     ...

         </xsd:schema>

           

        </types>

     <message name="CreateSatelliteRequest">

          <part name="request" element="tns:createSatellite"/>

     </message>

       

     <message name="CreateSatelliteResponse">

          <part name="response" element="tns:createSatelliteResponse"/>

     </message>

       

     <portType name="SatellitePortType"

               wsrp:ResourceProperties="tns:GenericSatelliteProperties">

          <operation name="createSatellite">

              <input message="tns:CreateSatelliteRequest"

                  wsa:Action="http://example.com/CreateSatellite" />

              <output message="tns:CreateSatelliteResponse"

                  wsa:Action="http://example.com/CreateSatelliteResponse" />

          </operation>

          <operation name="getAltitude">

              <input message="wsrpwsdl:GetResourcePropertyRequest"

                  wsa:Action="http://docs.oasis-open.org/wsrf/2004/

                  06/WS-ResourceProperties/GetResourceProperty/>

                <output message="wsrpwsdl:GetResourcePropertyResponse"

                    wsa:Action="http://docs.oasis-open.org/wsrf/2004/

                    06/WS-ResourceProperties/GetResourcePropertyResponse/>

            </operation>

        </portType>

        <binding name="SatelliteSoapBinding" type="tns:SatellitePortType">

            <soap:binding style="document"

                transport="http://schemas.xmlsoap.org/soap/http"/>

            <operation name="createSatellite">

                <input>

                    <soap:body use="literal"/>

                </input>

                <output>

                    <soap:body use="literal"/>

                </output>

            </operation>

            <operation name="getAltitude">

                <input>

                    <soap:body use="literal"/>

                </input>

                <output>

                    <soap:body use="literal"/>

                </output>

            </operation>

        </binding>

        <service name="SatelliteService">

            <port name="SatellitePort" binding=

            "tns:SatelliteSoapBinding">

                <soap:address location=

                "http://example.com/satellite"/>

            </port>

        </service>

    </definitions>

    一 开始是 portType,我们创建一个叫做 getAltitude 的新操作。该操作具有一个 input 和一个 output 消息,但是两个消息都已经定义在我们以前导入的 WS-ReferenceProperties.wsdl 文件中,所以我们需要做的就是使用适当的名称空间别名来引用它们。

    一旦创建了 operation,我们只要将它添加到 binding 就行了,而这一点我们已经很内行了。

    l         请求多个属性

    幸运的是,我们并不局限于检索单个属性值。我们也可以检索多个属性:

    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

            xmlns:sat="http://example.org/satelliteSystem"

            xmlns:wsa="http://www.w3.org/2005/02/addressing"

            xmlns:wsrp="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-Resour

    ceProperties-1.2-draft-01.xsd">

        <SOAP-ENV:Header>

           <wsa:Action>

                http://docs.oasis-open.org/wsrf/2004/06/

                WS-ResourceProperties/GetMultipleResourceProperties

           </wsa:Action>

           <wsa:To SOAP-ENV:mustUnderstand="1">

                http://example.com/satellite

           </wsa:To>

           <sat:SatelliteId>SAT9928</sat:SatelliteId>

        </SOAP-ENV:Header>

        <SOAP-ENV:Body>

           <wsrp:GetMultipleResourceProperties

                  xmlns:satProp="http://example.com/satellite">

              <wsrp:ResourceProperty>

              satProp:roll

              </wsrp:ResourceProperty>

              <wsrp:ResourceProperty>

              satProp:pitch

              </wsrp:ResourceProperty>

              <wsrp:ResourceProperty>

              satProp:yaw

              </wsrp:ResourceProperty>

           </wsrp:GetMultipleResourceProperties>

        </SOAP-ENV:Body>

    </SOAP-ENV:Envelope>

    同前面一样,Header 中的信息来自端点引用。

    l         接收多个属性

    响应消息类似于它的单个属性对应物:

    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

             xmlns:sat="http://example.org/satelliteSystem"

             xmlns:wsa="http://www.w3.org/2005/02/addressing"

             xmlns:wsrp="http://docs.oasis-open.org/wsrf/200

             4/06/wsrf-WS-ResourceProperties-1.2-draft-01.xsd">

        <SOAP-ENV:Header>

           <wsa:Action>

                http://docs.oasis-open.org/wsrf/2004/06/WS-Res

                ourceProperties/GetMultipleResourcePropertiesResponse

           </wsa:Action>

           <wsa:To SOAP-ENV:mustUnderstand="1">

                http://example.com/myClient

           </wsa:To>

        </SOAP-ENV:Header>

        <SOAP-ENV:Body>

           <wsrp:GetMultipleResourcePropertiesResponse    

                   xmlns:satProp="http://example.com/satellite">

              <satProp:roll>32</satProp:roll>

              <satProp:pitch>49</satProp:pitch>                    

              <satProp:yaw>0</satProp:yaw>

           </wsrp:GetMultipleResourcePropertiesResponse>

        </SOAP-ENV:Body>

    </SOAP-ENV:Envelope>

    同样,我们要将它添加到 WSDL 文件。

    l         WSDL 文件

    同样,因为我们传递的实际消息已经定义在 WS-ResourceProperties.wsdl 文件中,把该功能添加到应用程序所要做的就是创建一个新 operation:

    ...

        <message name="CreateSatelliteRequest">

            <part name="request" element=

            "tns:createSatellite"/>

        </message>

       

       <message name="CreateSatelliteResponse">

            <part name="response" element=

            "tns:createSatelliteResponse"/>

        </message>

       

        <portType name="SatellitePortType"

               wsrp:ResourceProperties =

               "tns:GenericSatelliteProperties">

            <operation name="createSatellite">

                <input message="tns:CreateSatelliteRequest"

                     wsa:Action=

                     "http://example.com/CreateSatellite" />

                <output message="tns:CreateSatelliteResponse"

                     wsa:Action=

                     "http://example.com/CreateSatelliteResponse" />

            </operation>

           

            <operation name="getAltitude">

                <input message=

                "wsrpwsdl:GetResourcePropertyRequest"

                     wsa:Action="http://docs.oasis-open.org/ws

                     rf/2004/06/WS-ResourceProperties/GetResourceProperty"/>

                <output message=

                "wsrpwsdl:GetResourcePropertyResponse"

                     wsa:Action="http://docs.oasis-open.org/wsrf/2004/0

                     6/WS-ResourceProperties/GetResourcePropertyResponse"/>

            </operation>

           

            <operation name="getOrientation">

                <input message="wsrpwsdl:

                GetMultipleResourcePropertiesRequest"

                     wsa:Action="http://docs.oasis-open.org/wsrf/2004/0

                     6/WS-ResourceProperties/GetMultipleResourceProperties"/>

                <output message=

                "wsrpwsdl:GetMultipleResourcePropertiesResponse"

                     wsa:Action=

                     "http://docs.oasis-open.org/wsrf/2004/06/WS-ResourcePro

                     perties/GetMultipleResourcePropertiesResponse"/>

            </operation>

           

        </portType>

       

        <binding name="SatelliteSoapBinding" type=

        "tns:SatellitePortType">

           <soap:binding style="document"

                  transport=

                  "http://schemas.xmlsoap.org/soap/http"/>

            <operation name="createSatellite">

                <input>

                    <soap:body use="literal"/>

                </input>

                <output>

                    <soap:body use="literal"/>

                </output>

            </operation>

            <operation name="getAltitude">

                <input>

                    <soap:body use="literal"/>

                </input>

                <output>

                    <soap:body use="literal"/>

                </output>

            </operation>

            <operation name="getOrientation">

                <input>

                    <soap:body use="literal"/>

                </input>

                <output>

                    <soap:body use="literal"/>

                </output>

            </operation>

        </binding>

       

        <service name="SatelliteService">

            <port name="SatellitePort" binding="tns:SatelliteSoapBinding">

                <soap:address location="http://example.com/satellite"/>

            </port>

        </service>

    </definitions>

    一旦我们将 getOrientation operation 添加到了 binding,它就可以由应用程序使用了。

    我们也可以查询属性,正如您马上就会看到的。

    l         使用 XPath 查询

    尽 管请求所需的属性相当直观,但是也有需要使用其他方法的情景。不是简单地按名称请求资源属性,我们可以使用 XPath 中可用的查询。(有关 XPath 的更多信息,请参阅 参考资料。)例如,如果不能确定某个特定的属性是否存在,您可能想要在属性上使用 XPath 函数。

    XPath 的 另一个有用功能是,能够请求多个相同命名的属性,或者甚至能够查询参数。我们将在“理解 WSRF(第 2 部分)”中做前一件事,而马上就会做后一件事。例如,我们可以与 boolean() 函数一起使用一个 XPath 表达式,来确定人造卫星是否指向正确的方向,而不用显式地分析数据:

    <SOAP-ENV:Envelope xmlns:SOAP-ENV=

    "http://schemas.xmlsoap.org/soap/envelope/"

            xmlns:sat="http://example.org/satelliteSystem"

            xmlns:wsa="http://www.w3.org/2005/02/addressing"

            xmlns:wsrp="http://docs.oasis-open.org/wsrf/20

            04/06/wsrf-WS-ResourceProperties-1.2-draft-01.xsd">

        <SOAP-ENV:Header>

           <wsa:Action>

                http://docs.oasis-open.org/wsrf/2004/06/WS-ResourcePro

                perties/QueryResourceProperties

           </wsa:Action>

           <wsa:To SOAP-ENV:mustUnderstand="1">

                http://example.com/satellite

           </wsa:To>

           <sat:SatelliteId>SAT9928</sat:SatelliteId>

        </SOAP-ENV:Header>

        <SOAP-ENV:Body>

           <wsrp:QueryResourceProperties>

              <wsrp:QueryExpression Dialect=

              "http://www.w3.org/TR/1999/REC-xpath-19991116">

                 boolean(/*/pitch=25 and /*/roll=0 and /*/yaw=10)

              </wsrp:QueryExpression>

           </wsrp:QueryResourceProperties>

        </SOAP-ENV:Body>

    </SOAP-ENV:Envelope>

    注 意 Dialect 属性的使用,以区分 XPath V1.0 (这里展示的)和 XPath V2.0(http://www.w3.org/TR/2003/WD-xpath20-20031112)。规范没有限制您可以支持的方言 (dialect),但是如果实现不认识 Dialect,它就会返回一个 fault 和错误。

    l         查询结果

    结果看起来非常像前面的两个响应:

    <SOAP-ENV:Envelope xmlns:SOAP-ENV=

    "http://schemas.xmlsoap.org/soap/envelope/"

            xmlns:sat="http://example.org/satelliteSystem"

            xmlns:wsa="http://www.w3.org/2005/02/addressing"

            xmlns:wsrp="http://docs.oasis-open.org/wsrf/20

            04/06/wsrf-WS-ResourceProperties-1.2-draft-01.xsd">

        <SOAP-ENV:Header>

           <wsa:Action>

                http://docs.oasis-open.org/wsrf/2004/06/

                WS-ResourceProperties/Quer

    yResourcePropertiesResponse

           </wsa:Action>

           <wsa:To SOAP-ENV:mustUnderstand="1">

                http://example.com/myClient

           </wsa:To>

        </SOAP-ENV:Header>

        <SOAP-ENV:Body>

           <wsrp:QueryResourcePropertiesResponse>

               false

           </wsrp:QueryResourcePropertiesResponse>

        </SOAP-ENV:Body>

    </SOAP-ENV:Envelope>

    在本例中,我们只是返回一个布尔值,但是您可以返回 XPath 可以返回的任何类型的值。

    l         WSDL 文件

    同样,我们向 WSDL 文件添加一个新 operation:

    ...

        <portType name="SatellitePortType"

              wsrp:ResourceProperties=

              "tns:GenericSatelliteProperties">

    ...

          <operation name="getOrientation">

              <input message=

              "wsrpwsdl:GetMultipleResourcePropertiesRequest"

                  wsa:Action="http://docs.oasis-open.org/wsrf/20

                04/06/WS-ResourceProperties/GetMultipleResourceProperties"/>

              <output message=

              "wsrpwsdl:GetMultipleResourcePropertiesResponse"

                  wsa:Action="http://docs.oasis-open.org/wsrf/2004/06/W

              S-ResourceProperties/GetMultipleResourcePropertiesResponse"/>

          </operation>

           

            <operation name="checkOrientation">

                <input message=

                "wsrpwsdl:QueryResourcePropertiesRequest"

                    wsa:Action="http://docs.oasis-open.org/wsrf/20

                    04/06/WS-ResourceProperties/QueryResourceProperties"/>

                <output message=

                "wsrpwsdl:QueryResourcePropertiesResponse"

                    wsa:Action="http://docs.oasis-open.org/wsrf/2004/06/W

                 S-ResourceProperties/QueryResourcePropertiesResponse"/>

            </operation>

           

        </portType>

       

        <binding name="SatelliteSoapBinding" type=

        "tns:SatellitePortType">

            <soap:binding style="document"

                transport="http://schemas.xmlsoap.org/soap/http"/>

    ...

            <operation name="getOrientation">

                <input>

                    <soap:body use="literal"/>

                </input>

                <output>

                   <soap:body use="literal"/>

                </output>

            </operation>

            <operation name="checkOrientation">

                <input>

                    <soap:body use="literal"/>

                </input>

                <output>

                    <soap:body use="literal"/>

                </output>

            </operation>

        </binding>

       

        <service name="SatelliteService">

            <port name="SatellitePort" binding=

            "tns:SatelliteSoapBinding">

                <soap:address location=

                "http://example.com/satellite"/>

            </port>

        </service>

    </definitions>

    这关注检索属性。现在来看设置属性的值。

    l         我们想要完成什么

    至此,我们创建了一个 WS-Resource,并且了解了一个或多个用于表示它的状态的属性。但是这与真正地操纵 WS-Resource 没有太大的关系。在本节中,我们来看添加、悬挂和删除 WS-Resource 的属性。

    至 此,我们的人造卫星已经在天空中相对于地球的轨道中稳定了,而不是观测到某些特定的东西了。在本节中,我们要添加一个 ResourceProperty,它表示一个特定的目标。然后我们通过更新位置属性将人造卫星移向该目标,然后再删除所创建的目标属性。最后,通过将适 当的操作添加到 WSDL 文件,我们将把所有事情综合在一起。

    l         添加属性

    向 WS-Resource 添加属性涉及到使用 Insert 元素:

    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

             xmlns:sat="http://example.org/satelliteSystem"

             xmlns:wsa="http://www.w3.org/2005/02/addressing"

             xmlns:wsrp="http://docs.oasis-open.org/wsrf/

         2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.xsd">

        <SOAP-ENV:Header>

           <wsa:Action>

               http://docs.oasis-open.org/wsrf/2004/06/W

               S-ResourceProperties/SetResourceProperties

           </wsa:Action>

           <wsa:To SOAP-ENV:mustUnderstand="1">

                http://example.com/satellite

           </wsa:To>

           <sat:SatelliteId>SAT9928</sat:SatelliteId>

        </SOAP-ENV:Header>

        <SOAP-ENV:Body>

           <wsrp:SetResourceProperties

                  xmlns:satProp="http://example.com/satellite">

               <wsrp:Insert>

                   <satProp:targetCoords>

                   36n11, 115w08

                   </satProp:targetCoords>

               </wsrp:Insert>

           </wsrp:SetResourceProperties>

        </SOAP-ENV:Body>

    </SOAP-ENV:Envelope>

    我们可以给这个新属性取任何好听的名字,但是我们必须允许该新元素在 Resource Properties 文档中。(当我们在 WSDL 文件 中调整 WSDL 文件时将来做这一件事。)

    l         添加属性的结果

    当成功添加、删除或更改属性之后,我们将会得到一个只是确认操作的响应消息:

    <SOAP-ENV:Envelope xmlns:SOAP-ENV=

    "http://schemas.xmlsoap.org/soap/envelope/"

              xmlns:sat="http://example.org/satelliteSystem"

              xmlns:wsa="http://www.w3.org/2005/02/addressing"

              xmlns:wsrp="http://docs.oasis-open.org/wsrf/

        2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.xsd">

        <SOAP-ENV:Header>

           <wsa:Action>

                http://docs.oasis-open.org/wsrf/2004/06/W

        S-ResourceProperties/SetResourcePropertiesResponse

           </wsa:Action>

           <wsa:To SOAP-ENV:mustUnderstand="1">

                http://example.com/myClient

           </wsa:To>

        </SOAP-ENV:Header>

        <SOAP-ENV:Body>

           <wsrp:SetResourcePropertiesResponse>

           </wsrp:SetResourcePropertiesResponse>

        </SOAP-ENV:Body>

    </SOAP-ENV:Envelope>

    该响应与 Update 和 Delete 操作产生的响应是相同的。

    l         更改属性值

    在 添加属性 中,我们添加了一个新属性,但是我们也能更改现有属性的值。例如,我们可以告诉系统,通过使用 Update 元素更改人造卫星的位置属性来移动人造卫星:

    <SOAP-ENV:Envelope xmlns:SOAP-ENV=

    "http://schemas.xmlsoap.org/soap/envelope/"

           xmlns:sat="http://example.org/satelliteSystem"

           xmlns:wsa="http://www.w3.org/2005/02/addressing"

           xmlns:wsrp="http://docs.oasis-open.org/wsrf/2004/0

        6/wsrf-WS-ResourceProperties-1.2-draft-01.xsd">

        <SOAP-ENV:Header>

           <wsa:Action>

                http://docs.oasis-open.org/wsrf/2004/06/WS-Re

           sourceProperties/SetResourceProperties

          </wsa:Action>

          <wsa:To SOAP-ENV:mustUnderstand="1">

               http://example.com/satellite

          </wsa:To>

         <sat:SatelliteId>SAT9928</sat:SatelliteId>

     </SOAP-ENV:Header>

     <SOAP-ENV:Body>

         <wsrp:SetResourceProperties

                 xmlns:satProp="http://example.com/satellite">

             <wsrp:Update>

                <satProp:latitude>36.11</satProp:latitude>

             </wsrp:Update>

             <wsrp:Update>

                <satProp:longitude>158.08</satProp:latitude>

             </wsrp:Update>

          </wsrp:SetResourceProperties>

       </SOAP-ENV:Body>

    </SOAP-ENV:Envelope>

    在本例中,我们使用了两个 Update 组件,但是我们实际上可以使用 Insert、Update 和 Delete 组件的任意组合。

    l         删除属性

    属性可以被完全删除。例如,如果我们决定不再观测某个特定的目标,就可以删除该属性:

    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"

             xmlns:sat="http://example.org/satelliteSystem"

             xmlns:wsa="http://www.w3.org/2005/02/addressing"

             xmlns:wsrp="http://docs.oasis-open.org/wsrf/2004/06/wsrf-WS-Resour

    ceProperties-1.2-draft-01.xsd">

        <SOAP-ENV:Header>

           <wsa:Action>

             http://docs.oasis-open.org/wsrf/2004/06/WS-Resou

             rceProperties/SetResourceProperties

           </wsa:Action>

           <wsa:To SOAP-ENV:mustUnderstand="1">

                http://example.com/satellite

           </wsa:To>

           <sat:SatelliteId>SAT9928</sat:SatelliteId>

        </SOAP-ENV:Header>

        <SOAP-ENV:Body>

           <wsrp:SetResourceProperties

                    xmlns:satProp="http://example.com/satellite">

               <wsrp:Delete resourceProperty="targetCoords"/>

           </wsrp:SetResourceProperties>

        </SOAP-ENV:Body>

    </SOAP-ENV:Envelope>

    同样,我们的资源属性文档的模式定义必须允许我们做这一更改。

    l         WSDL 文件

    同样,因为标准元素已经定义在 WS-ResourceProperties.wsdl 中,所以我们可以简单地添加新操作:

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

    <definitions name="Satellite"

        targetNamespace="http://example.com/satellite"

        xmlns="http://schemas.xmlsoap.org/wsdl/"

        xmlns:tns="http://example.com/satellite"

        xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing"

        xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"

        xmlns:wsrp="http://docs.oasis-open.org/wsrf/2004/06/

        wsrf-WS-ResourceProperties-1.2-draft-01.xsd"

        xmlns:wsrpwsdl="http://docs.oasis-open.org/wsrf/200

    4/06/wsrf-WS-ResourceProperties-1.2-draft-01.wsdl"

        xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">

       

        <wsdl:import namespace="http://docs.oasis-open.org/

     wsrf/2004/06/wsrf-WS-ResourceProperties-1.2-draft-01.wsdl"

            location="WS-ResourceProperties.wsdl" />

       

        <types>

            <xsd:schema

              targetNamespace="http://example.com/satellite"

                xmlns:xsd="http://www.w3.org/2001/XMLSchema">

               

                <xsd:import namespace=

          "http://schemas.xmlsoap.org/ws/2004/03/addressing"

                       schemaLocation="WS-Addressing.xsd" />

               

               <xsd:element name="createSatellite">

                   <xsd:complexType/>

               </xsd:element>

               

               <xsd:element name="createSatelliteResponse">

                   <xsd:complexType>

                       <xsd:sequence>

                           <xsd:element ref=

                           "wsa:EndpointReference"/>

                       </xsd:sequence>

                   </xsd:complexType>

               </xsd:element>

               

              <xsd:element name="latitude" type="xsd:float" />

              <xsd:element name="longitude" type="xsd:float" />

              <xsd:element name="altitude" type="xsd:float" />

              <xsd:element name="pitch" type="xsd:float" />

              <xsd:element name="yaw" type="xsd:float" />

              <xsd:element name="roll" type="xsd:float" />

              <xsd:element name="focalLength" type="xsd:float" />

              <xsd:element name="currentView" type="xsd:string" />

               

              <xsd:element name="GenericSatelliteProperties">

                  <xsd:complexType>

                      <xsd:sequence>

                          <xsd:element ref="latitude" minOccurs="1"

                          maxOccurs="1"/>

                          <xsd:element ref="longitude" minOccurs="1"

                          maxOccurs="1"/>

                          <xsd:element ref="altitude" minOccurs="1"

                          maxOccurs="1"/>

                          <xsd:element ref="pitch" minOccurs="1"

                          maxOccurs="1"/>

                          <xsd:element ref="yaw" minOccurs="1"

                          maxOccurs="1"/>

                          <xsd:element ref="roll" minOccurs="1"

                          maxOccurs="1"/>

                          <xsd:element ref="focalLength"

                          minOccurs="1" maxOccurs="1"/>

                          <xsd:element ref="currentView"

                          minOccurs="1" maxOccurs="1"/>

                          <xsd:any/>

                      </xsd:sequence>

                  </xsd:complexType>

               </xsd:element>

               

            </xsd:schema>

           

        </types>

        <message name="CreateSatelliteRequest">

            <part name="request" element="tns:createSatellite"/>

        </message>

       

        <message name="CreateSatelliteResponse">

            <part name="response" element=

            "tns:createSatelliteResponse"/>

        </message>

       

        <portType name="SatellitePortType"

                 wsrp:ResourceProperties=

                 "tns:GenericSatelliteProperties">

            <operation name="createSatellite">

                <input message="tns:CreateSatelliteRequest"

           wsa:Action="http://example.com/CreateSatellite" />

                <output message="tns:CreateSatelliteResponse"

                    wsa:Action=

              "http://example.com/CreateSatelliteResponse" />

            </operation>

           

            <operation name="getAltitude">

                <input message=

                "wsrpwsdl:GetResourcePropertyRequest"

                  wsa:Action="http://docs.oasis-open.org/wsr

    f/2004/06/WS-ResourceProperties/GetResourceProperty"/>

                <output message=

                "wsrpwsdl:GetResourcePropertyResponse"

          wsa:Action="http://docs.oasis-open.org/wsrf/2004/0

    6/WS-ResourceProperties/GetResourcePropertyResponse"/>

            </operation>

           

            <operation name="getOrientation">

                <input message=

             "wsrpwsdl:GetMultipleResourcePropertiesRequest"

          wsa:Action="http://docs.oasis-open.org/wsrf/2004/0

    6/WS-ResourceProperties/GetMultipleResourceProperties"/>

                <output message=

            "wsrpwsdl:GetMultipleResourcePropertiesResponse"

                          wsa:Action=

    "http://docs.oasis-open.org/wsrf/2004/06/WS-ResourceProp

    erties/GetMultipleResourcePropertiesResponse"/>

            </operation>

           

            <operation name="checkOrientation">

                <input message=

                    "wsrpwsdl:QueryResourcePropertiesRequest"

                   wsa:Action="http://docs.oasis-open.org/wsr

    f/2004/06/WS-ResourceProperties/QueryResourceProperties"/>

                <output message=

                   "wsrpwsdl:QueryResourcePropertiesResponse"

           wsa:Action="http://docs.oasis-open.org/wsrf/2004/0

    6/WS-ResourceProperties/QueryResourcePropertiesResponse"/>

            </operation>

           

            <operation name="addTarget">

                <input message=

                      "wsrpwsdl:SetResourcePropertiesRequest"

           wsa:Action="http://docs.oasis-open.org/wsrf/2004/0

    6/WS-ResourceProperties/SetResourceProperty"/>

                <output message=

                     "wsrpwsdl:SetResourcePropertiesResponse"

           wsa:Action="http://docs.oasis-open.org/wsrf/2004/0

    6/WS-ResourceProperties/SetResourcePropertyResponse"/>

            </operation>

            <operation name="moveToTarget">

                <input message=

                      "wsrpwsdl:SetResourcePropertiesRequest"

           wsa:Action="http://docs.oasis-open.org/wsrf/2004/0

    6/WS-ResourceProperties/SetResourceProperty"/>

                <output message=

                     "wsrpwsdl:SetResourcePropertiesResponse"

           wsa:Action="http://docs.oasis-open.org/wsrf/2004/0

    6/WS-ResourceProperties/SetResourcePropertyResponse"/>

            </operation>

            <operation name="removeTarget">

                <input message=

                      "wsrpwsdl:SetResourcePropertiesRequest"

                     wsa:Action="http://docs.oasis-open.org/ws

    rf/2004/06/WS-ResourceProperties/SetResourceProperty"/>

                <output message=

                     "wsrpwsdl:SetResourcePropertiesResponse"

           wsa:Action="http://docs.oasis-open.org/wsrf/2004/0

    6/WS-ResourceProperties/SetResourcePropertyResponse"/>

            </operation>

           

        </portType>

       

        <binding name="SatelliteSoapBinding"

        type="tns:SatellitePortType">

            <soap:binding style="document" transport=

                    "http://schemas.xmlsoap.org/soap/http"/>

            <operation name="createSatellite">

                <input>

                    <soap:body use="literal"/>

                </input>

                <output>

                    <soap:body use="literal"/>

                </output>

            </operation>

            <operation name="getAltitude">

                <input>

                    <soap:body use="literal"/>

                </input>

                <output>

                    <soap:body use="literal"/>

                </output>

            </operation>

            <operation name="getOrientation">

                <input>

                    <soap:body use="literal"/>

                </input>

                <output>

                    <soap:body use="literal"/>

                </output>

            </operation>

           <operation name="checkOrientation">

                <input>

                    <soap:body use="literal"/>

                </input>

                <output>

                    <soap:body use="literal"/>

                </output>

            </operation>

            <operation name="addTarget">

                <input>

                    <soap:body use="literal"/>

                </input>

                <output>

                    <soap:body use="literal"/>

                </output>

            </operation>

            <operation name="moveToTarget">

                <input>

                    <soap:body use="literal"/>

                </input>

                <output>

                    <soap:body use="literal"/>

                </output>

            </operation>

            <operation name="removeTarget">

                <input>

                    <soap:body use="literal"/>

                </input>

                <output>

                    <soap:body use="literal"/>

                </output>

            </operation>

        </binding>

       

        <service name="SatelliteService">

            <port name="SatellitePort"

            binding="tns:SatelliteSoapBinding">

                <soap:address location=

                "http://example.com/satellite"/>

            </port>

        </service>

    </definitions>

    还请注意,我们可以添加任意元素到 GenericSatelliteProperties,所以我们可以容易地添加新属性,比如 targetCoords。

    l         结束语

    在本教程,也即 4 篇关于 WSRF 的系列文章中的第一篇文章中,我们一开始解释了 WSRF 背后的目的,以及为什么单有 Web 服务还不够。然后解释了 WS-Resource 是有状态资源(比如数据库或卫星)与 Web 服务的组合。

    资源本身是由一系列属性来描述的,这些属性是与 WSDL 文件中的 Web 服务相关联的。我们还介绍了 WSDL 和 WS-Addressing 的基础,WSRF 使用 WS-Addressing 来指向一个特定的 WS-Resource 实例。

    我们介绍了创建 WS-Resources,了解了它们的属性,以及调整这些属性,以便操纵资源。

    在 本系列的以后部分中,我们将会介绍 WSRF 的一些更高级的用途,比如 ServiceGroups 和错误处理,以及 WS-Notifications。在本系列的最后一部分中,我们将把所有内容综合在一起,并编写一个应用程序,它使用类来实现本系列前两部分中讨论的每 个概念。

    l         参考资料

    Web 服务资源框架(Web Services Resource Framework,WSRF)涉及大量不同领域。下面是起步所需的一些参考资料:

    单击 下载本教程中介绍的完整 WSDL 文件。

    WSRF 和相关规范

    WSRF 文档 的主要位置在 Globus Alliance Web 站点上,但是最新的规范可以在 Oasis 处找到。文档包括:

    Web 服务资源框架(白皮书)

    The WS-Resource Framework

    WS-ResourceProperties (WSRF-RP)

    WS-ResourceLifetime (WSRF-RL)

    WS-ServiceGroup (WSRF-SG)

    WS-Base Faults (WSRF-BF)

    Web 服务和相关的规范

     

    Author: orangelizq
    email: orangelizq@163.com

  • 相关阅读:
    查看SQL Server被锁的表以及如何解锁【转】
    JQUERY的$(function(){})和window.onload=function(){}的区别【转】
    安装和使用Redis【转】
    RabbitMQ的简单应用【转】
    Redis集群的搭建【转】
    Spring--如何解决循环依赖
    分布式事务--2PC(两阶段提交)
    CAP理论
    JVM垃圾回收机制
    Redis面试题
  • 原文地址:https://www.cnblogs.com/victor-ma/p/3829340.html
Copyright © 2011-2022 走看看