|
<script type="text/javascript"><!---->
// --></script>
<noscript></noscript>
|
<!----><!----><!---->
|
级别: 初级
Bilal Siddiqui
(wap_monster@yahoo.com
), CEO
2002 年 3 月 01 日
简单对象访问协议(SOAP)提供对远程对象的访问。这些对象的示例是简单的 JavaBeans 组件或是企业 JavaBeans 组件和 COM/COM+ 对象等。这些对象驻留在不同企业内部并且可能存在于因特网的任何位置。因此,SOAP 通过因特网通信并且是一种在不同企业间交换信息的机制。在本文中,Bial 会详细的讨论 SOAP 通信,对象是怎样用 SOAP 公开其功能的,怎样调用 SOAP 对象,怎样在有 SOAP 意识的应用程序间交换信息。他还会展示第 1 部分中提到的 WSDL 应用程序的 SOAP 服务部署,以及远程服务器对它的调用。
<!----><!----><!---->
SOAP 和 WSDL
我在本系列文章的 第 1 部分
介绍了 WSDL。WSDL 描述了 Web 服务的接口。Web 服务所有者将用 SOAP 来实现他们的接口。因此, WSDL 服务
实际上作为 SOAP 服务
一样存在。一旦 Web 服务用户拥有 WSDL 文件,他或者她就知晓接口的细节。他或者她就会用 SOAP 来与 Web 服务通信。
可以把 Web 服务考虑为对象,可以通过 WSDL 接口公开并且使用 SOAP 通过因特网远程访问。既然服务是对象,那么肯定有每种服务的相关属性和每种服务调用的行为。SOAP 消息是 XML 文档,可通过 HTTP 工作。
为什么用 SOAP?
B2B(Business-to-business)和 A2A(application-to-application )需求表明企业之间为交换信息而相互通信。这种概念被用在 B2B、工作流和跨企业集成中。例如,设想一条垂直供应链,在链上一家企业为了满足它的客户需求而需要调用其提供者的服务。而一些提供者需要沿供应链进一步下行来调用其它企业的服务。
很明显,在此应用程序中互操作性是最为重要的。任何单个企业只能实现 SOAP 通信通道的一端。另一端将是因特网上 任何地方的实体
。
在最近几年里,企业之间的集成和互操作性已经成为软件工程师和企业的一个挑战性任务。平台相关性也成为取得集成和互操作性的一个大问题。SOAP 依然是在企业间取得集成和互操作性最简单的机制。
SOAP 体系结构
有了对 SOAP 和它的用途的基本理解,我现在就展开对其体系结构的讨论以了解一些深层知识。请参阅 图 1
, 在此图里面您可以识别典型 SOAP 通信体系结构中的一些组件:
- SOAP 客户机
- SOAP 服务器
- 实际服务
图 1. 一个典型 SOAP 通信体系结构的组件
让我解释上面所提到的每个实体的体系结构角色。下面的讨论参照 图 1
。
SOAP 客户机
SOAP 客户机
是一台有 SOAP 机制的机器,它可以产生 SOAP 请求并通过 HTTP 发送到服务器。一条 SOAP 请求是一种类型的 SOAP 消息,通常只有两种类型的 SOAP 消息:一条 SOAP 请求
就是一台 SOAP 客户机发送给 SOAP 服务器的内容,一条 SOAP 响应
就是 SOAP 服务器对 SOAP 客户机响应的内容。 清单 1
是典型的 SOAP 请求
,请参阅 清单 2
来回顾 SOAP 响应。
清单 1:一条简单的 SOAP 请求
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" >
<SOAP-ENV:Body>
<m:getListOfModels xmlns:m = "uri reference" >
</m:getListOfModels>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
|
SOAP 服务器
SOAP 服务器也是一台有 SOAP 机制的机器,能够接收来自 SOAP 客户机的请求,并对之作出适当的响应。这些编过码的响应会返回发出请求的 SOAP 客户机。在 SOAP 服务器内部有三个实体:
- 服务管理器
- 被部署服务的列表
- XML 转换程序
服务管理器负责根据请求管理服务。请参阅 清单 1
的服务请求,在这里元素 <m:getListOfModels xmlns:m="urn:MobilePhoneservice" >
包含了服务的名称。服务管理器会读取 SOAP 客户机想调用的 SOAP 服务的名称并检查所需的服务实际上是否驻留于这台 SOAP 服务器上。此后,它会查询被部署服务的列表(SOAP 服务器所托管的所有服务的列表)。若存在,服务管理器将把 SOAP 请求传送给 XML 转换程序。XML 转换程序就负责将 SOAP 请求的 XML 结构转换成程序员用来实现实际服务的编程语言(例如,Java 编程语言)的结构。还要负责将来自实际服务的响应转换回 SOAP 响应的 XML 结构。请参阅 清单 2
获得 SOAP 响应的说明。
清单 2:一条简单的 SOAP 响应
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<m:getListOfModelsResponse xmlns:m="urn:MobilePhoneservice">
<Model>M1</Model>
<Model>M2</Model>
<Model>M3</Model>
</m:getPriceResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
|
实际服务
图 1
中标有 actual service
的框就是实际服务驻留的位置。服务实现可以是:例如,COM 组件或 JavaBeans 组件的形式。XML 转换程序负责将 XML 结构转换成合适的方法调用。当 XML 转换程序调用了实际服务实现的某个方法时,这个方法就会完成它的工作并且将结果信息返回 XML 转换程序。
请看一看 图 1
中连接 XML translator 和 actual service 的箭头。箭头的两端同在一个企业内,这意味着同一个组织控制着通信两端的接口。与穿过企业边界的在 SOAP 客户机和 SOAP 服务器之间的箭头相比,这正是 SOAP 的目的所在。
SOAP 请求响应机制
当 SOAP 客户机向 SOAP 服务器发送 SOAP 消息时,用 HTTP 协议传输。这就叫做 SOAP 与 HTTP 绑定。当 SOAP 服务器收到消息时,将消息交给服务管理器。服务管理器检查被部署服务的列表,查找在 SOAP 消息中所需的服务。若没有查找到所请求的服务,它将请求失败返回给 SOAP 客户机。但是若此项服务可以提供,控制权由服务管理器转移给 XML 转换程序(转换程序完成合适语言的转换并访问实际服务实现)。服务实现会处理请求并将结果返回给 XML 转换程序。XML 转换程序将结果转换成 SOAP 客户机能够理解的 SOAP 响应(XML 文档)。然后又一次用 HTTP 绑定来传输 SOAP 响应。现在让我们看一下 SOAP 与 HTTP 的绑定细节。
SOAP 与 HTTP 绑定
当您将 SOAP 和 HTTP 绑定在一起或在 HTTP 上操作 SOAP 时,您实际上将 HTTP 报头加到了 SOAP 请求和响应上了。 清单 1
是典型 SOAP 请求的结构,而清单 3
、 4
、 5
和 6
都是完整的 HTTP 请求,用来演示如何将 HTTP 报头添加到 清单 1
上。相似地, 清单 7
是一条完整的 HTTP 响应,针对于来自 清单 2
的 SOAP 响应。
无论您何时在 HTTP 上使用 SOAP,Content-Type 字段必须是 text/xml
。现在您可以察看 清单 3
到 清单 7
的详情。
使用 HTTP 的 SOAP 请求
您可以将 SOAP 和 HTTP 的 POST
请求方法连用。为了发送一条 SOAP HTTP 请求,您需要在 HTTP 中提供一个 SOAPAction
报头字段。 SOAPAction 指定了 SOAP 请求的目的。服务器(例如过滤 HTTP 中 SOAP 请求消息的防火墙)可以用字段 SOAPAction 的值来做决定。
HTTP 客户机在发送一条 SOAP HTTP 请求时必须用此报头字段。SOAPAction 可以有如下几种值:SOAPAction:"URI-Reference"
SOAPAction:"filename"
SOAPAction:""
SOAPAction:
清单 3:演示 SOAPAction 报头字段中的 URI 引用
POST /Vendors HTTP/1.1
Host: www.mobilephoneservice.com
Content-Type:"text/xml";Charset="utf-8"
Content-Length: nnnn
SOAPACtion:"www.mobilephoneservice.com/Vendors/MobilePhoneservice#getListOfModels"
<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" >
<SOAP-ENV:Body>
<m:getListOfModels xmlns:m="urn:MobilePhoneservice" >
</m:getListOfModels>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
|
清单 3
在 SOAPAction 中包括如下 URI 引用: www.mobilephoneservice.com/Vendors/MobilePhoneservice#getListOfModels
这个 SOAPAction 展示了两部分内容。第一部分是一个特别 SOAP 部署的地址: www.mobilephoneservice.com/Vendors/MobilePhoneservice
第二部分是一个片段标识符,它给出了我们感兴趣的方法的名字(#getListOfModels)。
清单 4:演示 SOAPAction 报头字段中的一个文件名
POST /Vendors HTTP/1.1
Host: www.mobilephoneservice.com
Content-Type:"text/xml";Charset="utf-8"
Content-Length: nnnn
SOAPAction:"MobilePhoneservice#getListOfModels"
<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" >
<SOAP-ENV:Body>
<m:getListOfModels xmlns:m="urn:MobilePhoneservice" >
</m:getListOfModels>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
|
清单 4
在 SOAPAction 中包含一个文件名( MobilePhoneservice#getListOfModels
)。 MobilePhoneservice
文件必须出现在主机 URI( www.mobilephoneservice.com/Vendors
)中。 这个主机 URI 是在 HTTP 报头中 host 字段( www.mobilephoneservice.com
)和文件夹名( /Vendors
)的结合。
清单 5:演示 SOAPAction 报头中的空字符串
POST /Vendors HTTP/1.1
Host: www.mobilephoneservice.com
Content-Type:"text/xml";Charset="utf-8"
Content-Length: nnnn
SOAPAction:""
<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" >
<SOAP-ENV:Body>
<m:getListOfModels xmlns:m="urn:MobilePhoneservice" >
</m:getListOfModels>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
|
清单 5
在 SOAPAction 中包含一个空字符串("")。空字符串值表明 SOAP 的目的和 Host URI( www.mobilephoneservice.com/Vendors
)的目的是一样的。
清单 6:演示无值 SOAPAction 报头
POST /Vendors HTTP/1.1
Host: www.mobilephoneservice.com
Content-Type:"text/xml";Charset="utf-8"
Content-Length: nnnn
SOAPAction:
<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" >
<SOAP-ENV:Body>
<m:getListOfModels xmlns:m ="urn:MobilePhoneservice" >
</m:getListOfModels>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
|
清单 6
没有包含 SOAPAction 值。这表明没有关于消息目的的信息。
用 HTTP 的 SOAP 响应
响应将可能是两种类型的 SOAP 响应中的一种:
- 一个成功的 SOAP 操作产生 SOAP 结果
- 一个不成功的 SOAP 操作产生一条 SOAP 错误消息
清单 7:一条带有 HTTP 报头的成功 SOAP 响应
HTTP/1.1 Content-Type:"text/xml"; Charset="utf-8"
Content-Length: nnnn
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" >
<SOAP-ENV:Body>
<m:getListOfModelsResponse xmlns:m = "URI-Reference">
<model>m1</model>
<model>m2</model>
</m:getListOfModels>
</SOAP-ENV:Body>
|
清单 7
是第一种情况,在此可以从 SOAP 服务器取得有意义的结果。
清单 8
是一条典型的 SOAP 错误消息。SOAP HTTP 响应遵循 HTTP 中通信状态信息的 HTTP 状态码的语义。若在处理一条请求时发生一个 SOAP 错误,SOAP HTTP 服务器必须发出一条 HTTP 500 "Internal Server Error" 响应,同时在响应中包括一条带有 SOAP 出错元素的 SOAP 消息。
清单 8:一条带有 HTTP 报头的典型 SOAP 错误消息
HTTP/1.1 500 Internal Server Error
Content-Type: "text/xml"; Charset="utf-8"
Content-Length: nnnn
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" >
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultstring>Failed to process the request</faultstring>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
|
使用电子邮件的 SOAP
HTTP 不是唯一绑定 SOAP 消息的解决方案。若 HTTP 不合适,您可以用诸如 SMTP 的其它机制来用于 SOAP 绑定。将 SOAP 和 SMTP 绑定,您可以建立一条单向传输路由。两条单向消息可以用来建立请求/响应通信。 用 SMTP 来发送一条 SOAP 消息,您需要遵从以下步骤:
- 使用 MIME-Version 报头字段
MIME-Version
用一个版本号来区别不同的 MIME 版本。它应用邮件处理代理(例如一个 POP 服务器)来区别旧版本和新版本所生成的邮件消息。请参阅 清单 9
,它使用了一个 MIME-Version 报头字段。
清单 9:一个使用电子邮件的 SOAP 示例
TO: <info@waxsys.com>
From: <abc@punjab.com>
Reply-To: <abc@punjab.com>
Date: SAT, 2 Feb 2002 16:00:00
Message-Id: <4FAB345C8D93E93B7A6E9@punjab.com> MIME-Version: 1.0
Content-Type: text/xml; charset=utf-8
Content-Transfer-Encoding: QUOTED-PRINTABLE
<?xml version ="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<prnt:echoString xmlns:prnt="http://waxsys.com">
<msgString>Put your mail Message</msgString>
</prnt:echoString>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
|
- 使用 Content-Type 报头字段:
Content-Type
用来标识消息主体中的数据类型。对于 SOAP 消息 Content-Type 应该有一个值“text/xml”。请参阅 清单 9
,它使用了 Content-Type。
- 使用 Content-Transfer-Encoding 字段:
Content-Transfer-Encoding 用来指定传输编码的类型,也就是您所要传输的数据是字符格式还是二进制格式。 清单 9
使用 Quoted-Printable 编码,这种编码符合依照 ASCII 字符集的可打印字符。这种对数据的编码方式使邮件传输代理不可能修改结果八位元。请参阅 清单 9
,它使用了 Content-Transfer-Encoding 。
|
|
SOAP 模式与实现
SOAP 消息
一条 SOAP 消息只是一个 XML 文档,由一个强制性的 SOAP Envelope 组成,SOAP Envelope 有一个可选的 SOAP Header 和一个必须有的 SOAP Body。
SOAP 模式的元素:
- Envelope
- Header
- Body
- Fault
Envelope:
Envelope 是表示一条 SOAP 消息的顶层元素。为了发送一条 SOAP 消息,必须包括此元素。Envelope 使用必要的 SOAP 名称空间标识符( http://schemas.xmlsoap.org/soap/envelope/
)。若 Envelope 包含了错误的名称空间,会产生一个关于 Envelope 名称空间版本的错误。 清单 10
是一个空 Envelope。称其为“空 Envelope”是为了强调在通过“投递”发出它之前,它最终应该包含一封“信”(也许是商业信)。SOAP 模式中的“信”就是指“SOAP Body”,HTTP POST(在 HTTP 与 SOAP 的绑定一部分讨论过)就是传输机制。
清单 10:一个空 SOAP Envelope
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
</SOAP-ENV:Envelope>
|
Header:
SOAP Header 是可选的。您可以直接将 SOAP Body 放到 SOAP Envelope 中并完全忽略报头。报头提供了一个扩展 SOAP 消息功能的机制。例如,认证就是由 SOAP Header 条目所提供的一种典型扩展。在此情况下,将有一个认证框架,它会使用 SOAP 作为更低级别的传输。请参阅 清单 11
来查看在 SOAP 中的报头实现。
清单 11:在一个 SOAP Envelope 中的报头实现
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<m:Order xmlns:m="some URI" SOAP-ENV:mustUnderstand="1">
</m:Order>
</SOAP-ENV:Header>
</SOAP-ENV:Envelope>
|
Body:
Body 元素包含您实际要发送的消息。它是一个强制性的元素且其子元素通常属于一个用户定义的名称空间。 清单 12
展示了一条引用一个用户定义的名称空间 “u”
的 SOAP 消息。Body 元素是必要信息的容器。这个元素必须在 SOAP 消息中出现并且必须是 SOAP Envelope 元素的一个直接子元素。它也必须直接跟在 SOAP Header 元素的后面。若没有 Header 元素,那么它应直接跟在 Envelope 元素的后面。主体可以包含子元素并且子元素可能是受限于名称空间的。
清单 12: SOAP Envelope 内有 Header,还有 Body
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<m:Order xmlns:m="some URI" SOAP-ENV:mustUnderstand="1">
</m:Order>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<u:GetPrice xmlns:u="some URI" >
<model>m1</model>
</u:GetPrice>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
|
Fault:
这个元素表明一条错误消息。它应作为一个主体条目出现并且不能在 Body 元素中出现一次以上。通常,Fault 元素会在一条 SOAP 响应消息中出现,以表明在 SOAP 请求中出现错误。
Fault 的子元素:
faultcode
(错误的标识)
faultstring
(错误的描述)
faultactor
(标识由谁导致的错误)
detail
(错误细节。通常是一个应用程序特定错误,也就是说,它相当于在 SOAP 请求主体中用到地用户定义的名称空间)
清单 13
是一条典型的错误消息。
清单 13: 当应用程序出现错误时,SOAP Fault 的使用
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<m:Order xmlns:m="some URI" SOAP-ENV:mustUnderstand="1">
</m:Order>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<SOAP-ENV:Fault>
<faultcode>SOAP-ENV:Server</faultcode>
<faultstring>Not necessary information</faultstring>
<detail>
<d:faultdetail xmlns:d = "uri-referrence">
<msg>
application is not responding properly.
</msg>
<errorcode>12</errorcode>
</d:faultdetail>
</detail>
</SOAP-ENV:Fault>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
|
来自第 1 部分的一条对 WSDL 文件的 SOAP 请求
已经解释了 SOAP 消息(请求和响应)的常规语法,我将展示如何对本系列 第 1 部分
中的 MobilePhoneservice 开发一条 SOAP 请求。在第 1 部分中您设计一个完整的 WSDL 接口来解释 MobilPhoneservice。移动公司在 MobilePhoneservice 中提供了两种方法,一种是 getListOfModels()
,另一种是 getPrice(modelNumber)
。 GetListOfModels()
没有参数但是返回手机型号的一张列表,而 getPrice(modelNumber)
有一个参数 modelNumber
并返回需求型号的 price
。您将用 SOAP 请求格式对它作成文档,但是首先让我展示给您一般的 SOAP 请求和响应格式。
清单 14:SOAP 请求的一般格式
<SOAP-ENV:Envelope xmlns:SOAP-ENV ="SOAP schema's URI"
<SOAP-ENV:Body>
<Instance:"Method Name" xmlns:Instance= "URI where method is located">
<parameter1>value</parameter1>
<parametern>value</parametern>
</Instance:"Method Name">
</SOAP_Envelop:Body>
</SOAP-ENV:Envelope>
|
一条简单的 SOAP 请求或响应只能表明一种服务的一个方法。包含一条 SOAP 请求的 Envelope 的一般格式遵从 清单 14
。将这种一般格式与 清单 16
中的 getListOfModels()
的方法调用请求比较。在清单 16 中,我已经提供了方法和 URI 的名称。既然在 getListOfModels()
中不需要参数,所以 <m:getListOfModels>
在 清单 16
中是一个空元素。
清单 15:一条 SOAP 响应的一般格式
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<Instance:"Method Name"+"Response"
xmlns:Instance="URI where method is located">
<return>
<responseparameter1>value</responseparameter1>
<responseparametern>value</responseparametern>
</return>
</Instance: "Method Name"+"Response">
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
|
清单 15
是一条一般的 SOAP 响应。Apache SOAP 服务器在方法名称的后面增加了"Response"关键字并将返回值封入元素 <return>
中作为一个直接子方法元素。若返回值是复合型结构,那么 <return>
元素包含一个或多个 <item>
元素。将 清单 15
与 清单 17
相比,清单 17 是来自 getListOfModels()
的实际响应。 清单 17
包含一系列项目,作为 Vector 数据类型,它是返回参数。 相似地, 清单 18
和 19
展示了针对 MobilePhoneservice 的方法 getPrice()
的 SOAP 请求和响应。
清单 16:调用 getListOfModels() 方法的 SOAP 请求
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body>
<m:getListOfModels xmlns:m = "www.mobilphoneservice.com" >
</m:getListOfModels>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
|
清单 17:针对于来自清单 16 请求的 SOAP 响应
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
<ns1:getListOfModelsResponse xmlns:ns1="urn:MobilePhoneservice"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<return xmlns:ns2="http://xml.apache.org/xml-soap"
xsi:type="ns2:Vector">
<item xsi:type="xsd:string">M1</item>
<item xsi:type="xsd:string">M2</item>
<item xsi:type="xsd:string">M3</item>
<item xsi:type="xsd:string">M4</item>
<item xsi:type="xsd:string">M5</item>
</return>
</ns1:getListOfModelsResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
|
清单 18:对于 getPrice 方法的 SOAP 请求
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
<m:getPrice xmlns:m ="www.mobilphoneservice.com">
<modelNumber xsi:type ="xsd:String">M1</modelNumber>
</m:getPrice>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
|
清单 19:对于来自清单 18 请求的 SOAP 响应
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
<ns1:getPriceResponse xmlns:ns1="urn:MobilePhoneservice"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<return xsi:type="xsd:string"> 5000 </return>
</ns1:getPriceResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
|
在 SOAP 服务器上部署基于 WSDL 的服务
在此部分您将在 Apache SOAP 服务器上部署来自第 1 部分的 WSDL 服务。Apache SOAP 工具箱将 WSDL 服务信息保存在一个部署描述符文件里面。部署描述符包含了 WSDL 服务的名称和它拥有的所有方法。在运行时部署描述符会将这些名称提供给 SOAP 服务器。同样的部署描述符文件还包含了实现接口的 JavaBean 组件的地址。
清单 20:一个部署描述符的框架
<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment"
id="URN:SERVICE-URN">
<isd:provider type="java"
scope="Request"
methods="EXPOSED-METHODS">
<isd:java class="IMPLEMENTING-CLASS"/>
</isd:provider>
<isd:faultListener>org.apache.soap.server.DOMFaultListener
</isd:faultListener>
</isd:service>
|
清单 20
是一个部署描述符的框架,为了作为基于 WSDL 服务的部署描述符使用,它需要三项信息( URN:SERVICE-URN、EXPOSED-METHODS
和 IMPLEMENTING-CLASS
)。 URN:SERVICE-URN
是被部署服务的名称。在此例中它是 “urn:MobilePhoneservice”
。 EXPOSED-METHODS
是一个单空格分隔的由服务提供的方法的列表。 在此部署中它是 getListOfModels getPrice
。
IMPLEMENTING-CLASS 是带有全路径的 Java 类名称。例如, samples.phonequote.MobilePhoneservice
。 在此例中测试应用程序时,您有如下目录结构:
Apache SOAP 服务器: C:\foo\SOAP-2_2
Mobile phone 服务实现:
C:\foo\SOAP-2_2\samples\phonequote\MobilePhoneservice
因此,IMPLEMENTING-CLASS 路径请参照您安装 SOAP 工具箱的目录。 我没有提供 Java 类的实际实现。 它取决于业务逻辑并且可以是任何东西。
清单 21:MobilePhoneservice 的部署描述符
<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment"
id="urn:MobilePhoneservice">
<isd:provider type="java"
scope="Request"
methods="getListOfModels getPrice">
<isd:java class="samples.phonequote.MobilePhoneservice"/>
</isd:provider>
<isd:faultListener>
org.apache.soap.server.DOMFaultListener
</isd:faultListener>
</isd:service>
|
清单 21
是来自第 1 部分对 WSDL 文件的完整部署描述符。
SOAP 客户机与 SOAP 服务器的通信
我已经提供过一个应用程序样本来演示一台 SOAP 客户机与一台 SOAP 服务器的通信。 为此我给过三个列表:Startup.html( 清单 22
)、Operation.html( 清单 23
)和 Execute.jsp( 清单 24
)。
StartUp.html( 清单 22
)是一个简单的 HTML 文件,提供给用户一个 GUI 并询问他将要调用哪一个 SOAP 方法。用户会选择一个他需要的方法。
清单 22:一个作为前端的简单 HTML 页
<HTML>
<BODY bgcolor="Teal">
<br/>
<p align="center">
<font size="5" face="Arial" color="white"><b>
SOAP method invocation demo </b></font>
</p>
<hr/>
<font face="Arial" color="whitesmoke" size="3">
<br/><b>
Click any of the method name to execute.<br/>
1. Get the List of all Models that we manufacture....
<a href="execute.jsp?index=1">
<font color="orange"> GetListOfModels </font></a> <br/>
2. Get the Price of any particular model......................
<a href="operation.html">
<font color="orange"> GetPrice </font></a>
</b>
</BODY>
</HTML>
|
Operation.html( 清单 23
)将询问客户提供方法调用所需的参数。
清单 23:根据他或她所选择的方法给予客户一个 GUI
<HTML>
<BODY bgcolor="Teal">
<br/>
<p align="center">
<font size="5" face="Arial" color="white"><b>
GetPrice Operation input Form </b>
</font></p>
<hr/>
<p align="center">
<form action="execute.jsp" method="POST">
<input type="hidden" name="index" value="0">
<table textColor="white">
<tr><td>
<font color="whitesmoke"><b>Description :</b></font>
</td><td><font color="whitesmoke">
Method GetPrice is used to Get Price of given Model Number</font>
</td></tr>
<tr><td>
<font color="whitesmoke"><b>Parameter(s)</b></font></td><td>
</td></tr>
<tr><td><font color="whitesmoke">Model Number </td></font>
<td><font color="whitesmoke">
<input type="text" name="parameter" size="30">
(required) </font>
</td></tr>
<tr><td>
</td><td><input type="Submit" value="Invoke">
</td></tr>
</font>
</table>
</form>
</p>
</BODY>
</HTML>
|
Execute.jsp( 清单 24
)包含了所有的令人感兴趣的代码。它检测所调用的方法和所传递的参数。然后发送给远程服务器一个方法调用。
清单 24:检测方法并发送给远程服务器一个调用
<%@ page language="java" import="java.util.Vector" %>
<%@ page import="java.net.MalformedURLException, java.net.URL" %>
<%@ page import="java.util.Vector" %>
<%@ page import="org.apache.soap.SOAPException,
org.apache.soap.Constants" %>
<%@ page import="org.apache.soap.rpc.Call, org.apache.soap.rpc.Response,
org.apache.soap.rpc.Parameter" %>
<%@ page import="org.apache.soap.transport.http.SOAPHTTPConnection" %>
<%@ page import="org.apache.soap.Fault" %>
<HTML>
<BODY bgcolor="Teal">
<br/>
<p align="center">
<font color="whitesmoke">
<%
boolean isParameter = false ;
SOAPHTTPConnection soapTransport = new SOAPHTTPConnection();
// Address of the remote server.
// Normally this should be dynamically passed and detected.
// We have hard coded it only for demonstration.
URL url = new URL ("http://localhost:8080/soap/servlet/rpcrouter");
// Build the call.
Call call = new Call ();
call.setTargetObjectURI ("urn:MobilePhoneservice");
call.setSOAPTransport (soapTransport);
call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
// We'll detect which method user selected
// and give a call accordingly.
// We'll pass parameters if present.
if (request.getParameter("parameter")!=null)
isParameter = true;
if (request.getParameter("index").equals("0"))
{
call.setMethodName("getPrice");
Vector params = new Vector();
String message = new String (request.getParameter("parameter"));
params.addElement (new Parameter("message", String.class,
message , null));
call.setParams(params);
}
else
call.setMethodName("getListOfModels");
Response resp = call.invoke ( url, /* actionURI */ "" );
out.println("<p align=left>
<font size=\"4\" face=\"Arial\" color=\"white\">
Response of [ "+call.getMethodName()+" ]
</font><hr/>");
// Check the response.
if (resp.generatedFault ()) {
Fault fault = resp.getFault ();
out.println("<b>Fault is:</b>"+ fault.getFaultCode ()
+" ["+fault.getFaultString ()+"]");
} else {
Parameter result = resp.getReturnValue ();
out.println("<b>Response is: </b>"+ result.getValue ()+"");
}
%>
<font>
</p>
</BODY>
</HTML>
|
为了运行此应用程序,您需要两台 Apache SOAP 服务器。 一台服务器将用来与用户通信并托管 清单 22
、 23
和 24
。 另一台服务器(也称为远程服务器)就是我们需要部署第 1 部分所讲的基于 WSDL 服务的地方(在前一节描述,“ 在 SOAP 服务器上基于 WSDL 服务的部署
”)。 仅仅是为了演示,远程服务器的地址 http://localhost:8080/soap/servlet/rpcrouter
已经硬编码在 Execute.jsp( 清单 24
)中。在实际操作中您可以从 WSDL 文件中读取它。
SOAP 中的简单与复合数据类型
在此节中,我将从解释简单与复合数据类型的不同开始。然后展示如何在 SOAP 中对它们编码。
简单类型包括字符串、浮点数、整数、枚举等。 例如一部手机的“name”的数据类型就是 “string”
。 复合类型由简单类型组成但只代表一个实体。例如, “Student”
类型记录可以有不同的属性,如 “studentName”
属于类型 “string”
, “studentRollNumber”
属于类型 “int”
但都只代表一个实体 “Student”
。
清单 25
包含了一个名称为 “Mobile”
的复合数据类型。 您会在后面的 SOAP 请求中用到。
清单 25: “Mobile”类型的模式定义结构
1<? xml version="1.0" ?>
2<xsd:schema xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
3 xmlns:xsd="http://www.w3.org/1999/XMLSchema">
4 targetNameSpace= "www.mobilephoneservice.com/phonequote">
5 <xsd:element name ="Mobile">
6 <xsd:complexType>
7 <xsd:element name="modelNumber" type="xsd:int">
8 <xsd:element name="modelName" type="xsd:string">
9 <xsd:element name="modelWeight" type="xsd:int">
10 <xsd:element name="modelSize" type="xsd:int">
11 <xsd:element name= | |
相关推荐
在本系列文章中,我们将研究创建、部署和发布 Web 服务的所有主要技术方面,从 Web 服务描述语言(WSDL),到简单对象访问协议(SOAP),以及通用描述、发现和集成(UDDI)注册中心。 在 Web 服务中,WSDL扮演着...
WSDL 与简单对象访问协议 (SOAP) 密切相关。SOAP 是一种基于 XML 的协议,用于在不同系统之间进行消息传递。WSDL 文件通常定义了服务的 SOAP 绑定,包括使用 SOAP 的消息结构、命名空间等。SOAP 消息通常通过 HTTP ...
在使用 WSDL 部署 Web 服务时,需要定义服务的访问点、操作和绑定。服务的访问点是指 Web Services 提供的操作的入口点,操作是指 Web Services 提供的功能,绑定是指特定端口类型的具体协议和数据格式定义。绑定...
【描述】:在Java开发中,Apache CXF是一个广泛使用的开源框架,它允许开发者构建和部署Web服务。"Java 2 WSDL"指的是从Java类生成WSDL(Web Services Description Language)文件的过程。这通常在我们需要为已有的...
2. **WSDL生成**:使用Java的JAX-WS(Java API for XML Web Services)或其他类似框架,你可以自动生成服务的WSDL描述。这个WSDL文件将详细列出服务的所有接口和参数。 3. **SOAP消息处理**:服务端需要解析接收到...
3. 部署服务:将SEI类部署到Web服务器上,例如Tomcat或Jetty,使得客户端可以通过SOAP请求访问服务。 三、Android客户端调用SOAP服务 1. 添加依赖库:Android客户端通常使用Ksoap2库来处理SOAP通信。在build.gradle...
简单对象访问协议(SOAP,Simple Object Access Protocol)是一种基于XML的网络协议,旨在促进不同平台和应用程序之间的互操作性。SOAP结合了HTTP的普遍性和XML的灵活性,使得现有的应用程序能够更容易地通过网络...
Apache Axis2 是一个流行的开源Web服务引擎,它允许开发者创建和部署高级Web服务。这个框架是基于Apache SOAP项目,提供了一种...这个过程展示了Axis2作为Web服务框架的强大功能,使得开发和部署Web服务变得简单易行。
- **服务发布**:服务提供者创建WSDL文档,描述其服务的接口、消息格式和访问方式,然后将其部署到可访问的URL。 - **服务发现**:服务消费者通过UDDI(Universal Description, Discovery, and Integration)或其他...
【标题】"WebService之WSDL和SOAP实例(基于JAVA)"主要涵盖了两个核心概念:Web服务描述语言(WSDL)和简单对象访问协议(SOAP),这些都是在Java环境下实现Web服务的关键技术。 **Web服务描述语言(WSDL)** WSDL是...
### 简单对象访问协议(SOA)实验详解 #### 实验概述 本实验旨在通过实践操作加深学生对简单对象访问协议(SOAP)的理解。实验不仅涵盖了SOAP的基本概念,还包括了如何利用SOAP来构建Web服务及其客户端的具体步骤。...
SOAP(简单对象访问协议)则是一种基于XML的消息传递协议,常用于Web服务的通信。当Java类被用来实现Web服务时,JAVA2WSDL工具可以帮助快速生成描述这些服务的WSDL文件,从而简化Web服务的发布过程。 SOAP生成工具...
WSDL通常与SOAP(Simple Object Access Protocol)一起使用,SOAP是一种基于XML的消息传递协议,用于在Web服务中传输数据。此外,WSDL文档常与UDDI(Universal Description, Discovery and Integration)服务配合,...
开发者可以使用各种工具,如Apache Axis2、CXF和XFire等,来生成和处理WSDL文档,简化Web服务的开发和部署流程。 总之,WSDL文件是Web服务的重要组成部分,它定义了服务的接口、消息结构和通信机制,为服务的发现、...
8. **部署Web服务**:通常,将Java Web服务部署到应用服务器,如Tomcat、Jetty或Glassfish等,服务端点(Endpoint)可以通过URL访问。 9. **调试和测试**:可以使用工具如SoapUI进行Web服务的测试和调试,检查请求...
标题"D6 SOAP_WEB SERVICE"指的是使用Delphi编程语言开发基于SOAP(简单对象访问协议)的Web服务。在本文中,我们将深入探讨这个主题,了解如何使用Delphi构建Web服务以及SOAP在其中的作用。 首先,让我们了解一下...
1. **简单对象访问协议 (SOAP)**:SOAP 是一种轻量级协议,用于在Web服务中交换结构化的信息。它定义了一种消息格式,支持不同系统间的通信。 2. **Web 服务描述语言 (WSDL)**:WSDL 提供了一种标准的方式来描述Web...
WSDL在Web服务的开发和部署中起到关键作用,它使得服务能够被自动部署、发现和调用,例如通过UDDI(Universal Description, Discovery, and Integration)进行服务注册和查找,以及通过AJAX(Asynchronous ...
2. **Concrete Definitions (具体定义)**:这部分描述了服务的实际实现细节,如消息的序列化方式、通信协议的选择以及服务的访问地址等。这部分内容是特定于实现的,反映了服务的具体部署环境。 ### WSDL文档结构 ...
2. **生成Java类**:使用JAX-WS工具从WSDL生成Java服务接口和服务实现类。 3. **实现服务**:在生成的服务实现类中编写业务逻辑。 4. **部署服务**:将服务部署到支持JAX-WS的服务器,如Tomcat或JBoss。 5. **消费...