SOAP Web服务教程:什么是SOAP协议?示例

什么是 SOAP?

SOAP是一种基于XML的协议,用于通过HTTP访问Web服务。它有一些规范,可以在所有应用程序中使用。

SOAP被称为简单对象访问协议(Simple Object Access Protocol),但后来简称SOAP v1.2。SOAP是一种协议,换句话说,它定义了Web服务如何相互通信,或者如何与调用它们的客户端应用程序通信。

SOAP被开发为一种中间语言,以便用不同编程语言构建的应用程序可以轻松地相互通信,并避免大量的开发工作。

SOAP简介

在当今世界,有大量的应用程序是用不同的编程语言构建的。例如,可能有一个用Java设计的Web应用程序,另一个用.Net,还有一个用PHP

在当今网络世界中,应用程序之间的数据交换至关重要。但这些异构应用程序之间的数据交换将是复杂的。实现这种数据交换的代码复杂性也会很高。

解决这种复杂性的一种方法是使用XML(可扩展标记语言)作为应用程序之间数据交换的中间语言。

每种编程语言都可以理解XML标记语言。因此,XML被用作数据交换的基础媒介。

但是,关于在所有编程语言中如何使用XML进行数据交换,并没有标准规范。这就是SOAP软件的用武之地。

SOAP被设计为通过HTTP与XML配合使用,并具有某种可在所有应用程序中使用的规范。我们将在后续章节中进一步详细探讨SOAP协议。

SOAP的优点

SOAP是用于应用程序之间数据交换的协议。以下是一些使用SOAP的原因。

  • 开发基于SOAP的Web服务时,您需要一种语言,可用于Web服务与客户端应用程序进行通信。SOAP是为实现此目的而开发的完美媒介。该协议也受到W3C联盟(所有Web标准的管理机构)的推荐。
  • SOAP是一种轻量级协议,用于应用程序之间的数据交换。请注意关键词“轻量”。由于SOAP编程基于XML语言,而XML本身就是一种轻量级数据交换语言,因此SOAP作为一种协议也属于同一类别。
  • SOAP被设计为平台无关和操作系统无关的。因此,SOAP协议可以在Windows和Linux平台上的任何基于编程语言的应用程序中运行。
  • 它在HTTP协议上工作——SOAP在HTTP协议上工作,HTTP协议是所有Web应用程序使用的默认协议。因此,运行基于SOAP协议构建的Web服务在万维网上工作不需要任何类型的定制。

SOAP构建块

SOAP规范定义了所谓的“SOAP消息”,它就是发送给Web服务和客户端应用程序的内容。

SOAP架构的下图展示了SOAP消息的各种构建块。

SOAP Building Blocks
SOAP消息构建块

SOAP消息只不过是一个具有以下组件的XML文档。

  • 一个标识XML文档为SOAP消息的Envelope元素——这是SOAP消息的包含部分,用于封装SOAP消息中的所有细节。它是SOAP消息的根元素。
  • 包含头信息的Header元素——Header元素可以包含诸如调用应用程序可以使用的认证凭据等信息。它还可以包含SOAP消息中可以使用的复杂类型的定义。默认情况下,SOAP消息可以包含简单类型(如字符串和数字)的参数,但也可以是复杂对象类型。

一个简单的SOAP服务复杂类型示例如下所示。

假设我们想要发送一个包含“教程名称”和“教程描述”组合的结构化数据类型,那么我们将按如下所示定义复杂类型。

复杂类型由元素标签 <xsd:complexType> 定义。结构的所有必需元素及其各自的数据类型都在复杂类型集合中定义。

<xsd:complexType>     
 <xsd:sequence>       
 	<xsd:element name="Tutorial Name" type="string"/>         
  	<xsd:element name="Tutorial Description"  type="string"/>
  </xsd:sequence>
</xsd:complexType>
  • 一个包含调用和响应信息的Body元素——此元素包含需要在Web服务和调用应用程序之间发送的实际数据。以下是一个SOAP Web服务示例,其中SOAP主体实际上作用于在Header部分定义的复杂类型。这是发送给调用此Web服务的应用程序的“教程名称”和“教程描述”的响应。
<soap:Body>
   <GetTutorialInfo>
		<TutorialName>Web Services</TutorialName> 
		<TutorialDescription>All about web services</TutorialDescription> 
   </GetTutorialInfo>
</soap:Body>

SOAP消息结构

需要注意的是,SOAP消息通常在Web服务被调用时自动生成。

每当客户端应用程序调用Web服务中的方法时,Web服务将自动生成一个SOAP消息,该消息将包含从Web服务发送到客户端应用程序的数据的必要详细信息。

如本SOAP教程前一主题所述,一个简单的SOAP消息具有以下元素——

  • 信封元素
  • Header元素和
  • Body元素
  • Fault元素(可选)

让我们看一个简单的SOAP消息的示例如下,并看看每个元素实际做什么。

SOAP Message Structure

SOAP消息结构
  1. 从上面的SOAP消息可以看出,SOAP消息的第一部分是信封元素,用于封装整个SOAP消息。
  2. 下一个元素是SOAP主体,它包含实际消息的详细信息。
  3. 我们的消息包含一个名为“Guru99WebService”的Web服务。
  4. “Guru99Webservice”接受一个类型为“int”且名为“TutorialID”的参数。

现在,上述SOAP消息将在Web服务和客户端应用程序之间传递。

您可以看到以上信息对客户端应用程序多么有用。SOAP消息告诉客户端应用程序Web服务的名称、它期望的参数以及Web服务接受的每个参数的类型。

SOAP信封元素

构建块的第一部分是SOAP信封。

SOAP信封用于封装SOAP消息的所有必要细节,这些消息在Web服务和客户端应用程序之间交换。

SOAP信封元素用于指示SOAP消息的开始和结束。这使得调用Web服务的客户端应用程序能够知道SOAP消息何时结束。

关于SOAP信封元素,可以注意以下几点。

  • 每个SOAP消息都需要有一个根Envelope元素。SOAP消息绝对必须包含一个Envelope元素。
  • 每个Envelope元素至少需要有一个SOAP Body元素。
  • 如果Envelope元素包含Header元素,则其包含的Header元素不能超过一个,且必须作为Envelope的第一个子元素出现,位于Body元素之前。
  • SOAP版本改变时,信封也会改变。
  • 符合v1.1的SOAP处理器在收到包含v1.2信封命名空间的消息时会生成故障。
  • 符合v1.2的SOAP处理器在收到不包含v1.2信封命名空间的消息时会生成版本不匹配故障。

以下是SOAP信封元素版本1.2的SOAP API示例。

<?xml version="1.0"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://www.w3.org/2001/12/soap-envelope" SOAP-ENV:encodingStyle=" http://www.w3.org/2001/12/soap-encoding">
          <soap:Body>
        <Guru99WebService xmlns="http://tempuri.org/">
                  <TutorialID>int</TutorialID>
                </Guru99WebService>
          </soap:Body>
</SOAP-ENV:Envelope>

故障消息

当向SOAP Web服务发出请求时,返回的响应可以是两种形式:成功响应或错误响应。当生成成功时,服务器的响应将始终是SOAP消息。但如果生成SOAP故障,它们将作为“HTTP 500”错误返回。

SOAP故障消息包含以下元素。

  1. <faultCode>– 这是指定错误代码的代码。故障代码可以是以下任何值:
    1. SOAP-ENV:VersionMismatch – 当遇到SOAP Envelope元素的无效命名空间时。
    2. SOAP-ENV:MustUnderstand – Header元素的即时子元素,其mustUnderstand属性设置为“1”,但未被理解。
    3. SOAP-ENV:Client – 消息格式不正确或包含不正确的信息。
    4. SOAP-ENV:Server – 服务器出现问题,因此消息无法继续处理。
  2. <faultString> – 这是给出错误详细描述的文本消息。
  3. <faultActor> (可选)– 这是一个文本字符串,指示是谁导致了故障。
  4. <detail>(可选) – 这是用于应用程序特定错误消息的元素。因此,应用程序可以针对不同的业务逻辑场景拥有特定的错误消息。

故障消息示例

故障消息示例如下。如果客户端尝试在GetTutorial类中使用名为TutorialID的方法,则会生成此错误。

如果方法在定义的类中不存在,则会生成以下故障消息。

<?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>
         <SOAP-ENV:Fault>
         <faultcode xsi:type="xsd:string">SOAP-ENV:Client</faultcode>
        <faultstring xsi:type="xsd:string">
            Failed to locate method (GetTutorialID) in class (GetTutorial)
         </faultstring>
    </SOAP-ENV:Fault>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

输出

执行上述代码时,将显示“未能定位类(GetTutorial)中的方法(GetTutorialID)”之类的错误。

SOAP通信模型

所有SOAP通信都通过HTTP协议完成。在SOAP之前,许多Web服务都使用标准的RPC(远程过程调用)风格进行通信。这是最简单的通信类型,但它有很多限制。

现在,在本SOAP API教程中,让我们考虑下图,看看这种通信是如何工作的。在这个示例中,我们假设服务器托管了一个Web服务,该服务提供了两个方法:

  • GetEmployee – 这将获取所有员工详情
  • SetEmployee – 这将相应设置员工部门、薪资等详细信息的值。

在正常的RPC风格通信中,客户端只需在其请求中调用方法并向服务器发送所需的参数,然后服务器将向客户端发送所需的响应。

SOAP Communication Model

上述通信模型存在以下严重限制:

  1. 不依赖语言 – 托管方法的服务器将使用特定的编程语言,通常对服务器的调用也仅限于该编程语言。
  2. 非标准协议 – 当调用远程过程时,该调用并非通过标准协议执行。这是一个问题,因为Web上的所有通信大多必须通过HTTP协议完成。
  3. 防火墙 – 由于RPC调用不通过正常协议,因此服务器上需要打开单独的端口以允许客户端与服务器通信。通常,所有防火墙都会阻止此类流量,并且通常需要进行大量配置以确保客户端和服务器之间的此类通信能够正常工作。

为了克服上述所有限制,SOAP将使用以下通信模型:

SOAP Communication Model

  1. 客户端将关于过程调用和任何参数的信息格式化为SOAP消息,并作为HTTP请求的一部分发送到服务器。这种将数据封装到SOAP消息中的过程被称为封送(Marshalling)。
  2. 服务器将解封客户端发送的消息,查看客户端请求的内容,然后以SOAP消息的形式将适当的响应发送回客户端。解封客户端发送的请求的做法被称为解封(Demarshalling)。

SOAP实用示例

现在在这个SoapUI教程中,我们来看一个实际的SOAP例子,

可能了解SOAP消息如何生成的最佳方法是实际查看Web服务的运行情况。

本主题将探讨如何使用Microsoft.Net框架构建ASMX Web服务。这种Web服务支持SOAP版本1.1和版本1.2。

ASMX Web服务会自动生成Web服务描述语言(WSDL)文档。客户端调用应用程序需要此WSDL文档,以便应用程序知道Web服务能够做什么。

在我们的示例中,我们将创建一个简单的Web服务,用于向调用该Web服务的应用程序返回一个字符串。

这个Web服务将托管在一个Asp.Net Web应用程序中。然后我们将调用该Web服务并查看Web服务返回的结果。

Visual Studio还将向我们展示Web服务与调用应用程序之间传递的SOAP消息。

设置我们的Web服务应用程序的第一个先决条件可以通过以下步骤完成。

请确保您的系统已安装Visual Studio 2013,以进行本示例。

步骤1) 第一步是创建一个空的ASP.Net Web应用程序。在Visual Studio 2013中,点击菜单选项“文件”->“新建项目”。

SOAP Message Example

点击“新建项目”选项后,Visual Studio将显示另一个对话框,用于选择项目类型并提供项目所需详细信息。这将在下一步中解释。

步骤 2) 在此步骤中,

  1. 请务必首先选择ASP.NET Web应用程序的C# Web模板。项目必须是这种类型才能创建SOAP服务项目。通过选择此选项,Visual Studio将执行必要的步骤来添加任何基于Web的应用程序所需的必需文件。
  2. 为您的项目命名,在本例中为webservice.asmx。然后确保指定项目文件的存储位置。

SOAP Message Example

完成后,您将在Visual Studio 2013的解决方案资源管理器中看到已创建的项目文件。

SOAP Message Example

步骤 3) 在此步骤中,

我们将向项目添加一个Web服务文件。

  1. 首先右键单击项目文件,如下图所示

SOAP Message Example

  1. 右键单击项目文件后,您可以选择“添加->Web服务(ASMX)”选项来添加一个Web服务文件。只需为Web服务文件名提供一个“Tutorial Service”的名称即可。

SOAP Message Example

步骤4) 将以下代码添加到您的Tutorial Service asmx文件中。

SOAP Message Example

代码解释

  1. 这行代码为您的Web服务文件提供一个名称。这是重要的一步,因为它允许客户端应用程序通过Web服务的名称调用Web服务。
  2. 通常,类文件用于封装Web服务的功能。因此,类文件将包含所有Web方法的定义,这些方法将向客户端应用程序提供一些功能。
  3. 这里[WebMethod]被称为描述函数的属性。后续步骤创建一个名为“Guru99WebService”的函数,但通过添加[WebMethod]属性,确保该方法可以被客户端应用程序调用。如果此属性不存在,则该方法永远无法被客户端应用程序调用。
  4. 这里我们定义了一个名为“Guru99WebService”的函数,它将用于向调用客户端应用程序返回一个字符串。此函数是一个Web服务,可以被任何客户端应用程序调用。
  5. 我们使用return语句将字符串“This is a Guru99 Web service”返回给客户端应用程序。

如果代码成功执行,在浏览器中运行代码时将显示以下输出。

输出

SOAP Message Example

  • 输出清楚地显示,我们的Web服务名称是“Guru99 Web Service”,这是为我们的Web服务命名的结果。
  • 我们还可以看到我们可以调用Web服务。如果点击“调用”按钮,我们将在Web浏览器中得到以下响应。

SOAP Message Example

以上输出,

  • 它清楚地表明,通过调用Web方法,字符串“This is a Guru99 Web service”被返回。
  • Visual Studio还允许您查看调用上述Web服务时生成的SOAP消息请求和响应。

调用Web服务时生成的SOAP请求如下所示。

SOAP Message Example

代码解释

  1. SOAP消息的第一部分是信封元素,这在前面的章节中已经讨论过。这是每个SOAP消息中都存在的封装元素。
  2. SOAP主体是下一个元素,它包含SOAP消息的实际详细信息。
  3. 第三部分是指定我们想要调用名为“Guru99WebService”的服务元素。

SOAP Message Example

<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  
    <soap:Body>
      
        <Guru99WebServiceResponse xmlns="http://tempuri.org/">
          
            <Guru99WebServiceResult>string</Guru99WebServiceResult>
          
        </Guru99WebServiceResponse>
    </soap:Body>
</soap:Envelope>

代码解释

  1. SOAP消息的第一部分是信封元素,这在前面的章节中已经讨论过。这是每个SOAP消息中都存在的封装元素。
  2. SOAP主体是下一个元素,它包含SOAP消息的实际详细信息。
  3. 现在您将看到的有趣部分是“string”属性。这告诉客户端应用程序,被调用的Web服务返回一个字符串类型的对象。这非常有用,因为如果客户端应用程序不知道Web服务返回什么。

摘要

  • SOAP是一种用于在用不同编程语言构建的应用程序之间交换数据的协议。
  • SOAP基于XML规范,并与HTTP协议协同工作。这使其非常适合在Web应用程序中使用。
  • SOAP构建块由SOAP消息组成。每条SOAP消息都包含一个信封元素、一个头部和一个主体元素。
  • 信封元素是SOAP消息中强制性的元素,用于封装SOAP消息中的所有数据。
  • Header元素可用于包含身份验证信息或复杂数据类型定义等信息。
  • 主体元素是主要元素,包含Web方法的定义以及任何所需的参数信息。