[转]理解WSRF之一 使用WS-ResourceProperties (整理自IBM网站)

时间:2021-01-07 20:08:24

理解 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