SOAP協議和基於SOAP的開發流程詳述


【文章摘要】
簡單對象訪問協議(SOAP)是交換數據的一種協議規范,是一種輕量的、簡單的、基於XML的協議,它被設計成在WEB上交換結構化的和固化的信息。
在實際的軟件開發項目中,SOAP大多用於處理用戶數據,也即實現開戶、銷戶、改戶和查戶等功能。
本文根據作者實際從事過的基於SOAP的項目開發,對SOAP協議和基於SOAP的開發流程進行了詳細的介紹。希望大家通過此文,能夠對基於SOAP協議的開發有一個全面的了解。

一、soapUI和SOAP代碼生成框架簡介
“工欲善其事,必先利其器”,為了基於SOAP協議進行開發,我們需要事先准備好相關的工具軟件。在我最開始進行開發的時候,並沒有考慮到工具的重要性,等代碼寫好之后才發現沒有自測的工具,這個時候才匆忙地找同事要相關的軟件來安裝。這樣做影響了工作的效率。因此,“兵馬未動,糧草先行”,代碼未寫,工具要先裝好。
下面來介紹與SOAP相關的兩個軟件:soapUI和SOAP代碼生成框架。
1.soapUI
soapUI是一個基於SOAP的模擬測試工具,用於模擬WEB客戶端向SOAP消息處理模塊(我們要開發的模塊)發消息。我們可以用該軟件來對自己所編寫的程序進行單元和集成測試。
圖1是soapUI的軟件界面。

圖1 soapUI的軟件界面

2.SOAP代碼生成框架
在基於SOAP進行開發的時候,我們會用到很多SOAP自帶的、已經封裝好了的函數。為了避免重復勞動,SOAP的設計者為我們提供了一套叫做gsoap的自動生成代碼的框架。只要我們將wsdl文件(后面介紹)准備好,用兩個簡單的命名即可生成我們在開發過程中需要用到的相關函數文件。
不管大家在哪個平台(Windows、Linux或Mac OS)下開發程序,都可以利用此框架來生成代碼。自動生成代碼的工具布局如圖2所示。

圖2 自動生成代碼的工具布局
我們將相應的wsdl文件放入對應的文件夾中即可生成代碼框架。

二、基於SOAP開發的軟件模塊架構
一般說來,發送SOAP消息的都是與用戶直接打交道的外部模塊,這些消息需要轉變為內部消息之后,才能夠用於執行具體的處理。因此,基於SOAP開發的軟件模塊架構如圖3所示。

圖3 基於SOAP開發的軟件模塊架構
從圖3可以看出,系統一般不會直接用SOAP消息來執行具體的業務邏輯,而是用一個中間模塊將SOAP消息轉換為系統內部約定好的協議,然后由具體的業務執行模塊按照內部協議來執行具體的操作。
這樣做的好處有:
第一,將消息轉換與業務執行分離開來,便於程序實現和問題排查。
第二,不將業務的具體執行流程暴露出去,系統的安全性能更高。
第三,如果外部的SOAP協議經常變化,只需要修改中間的SOAP協議轉換模塊即可,不用讓具體業務處理模塊經常變動而影響了正常業務的執行。

三、基於SOAP的具體開發流程
准備工作都做好之后,我們接下來就要動手編寫程序了。下面以實現用戶數據的管理(即:增刪改查)為例,介紹整個開發的流程。
1.編寫wsdl文件
wsdl文件,也即是SOAP協議文件,用於約定要執行哪些具體操作。例如,我們要在系統中執行開戶操作,需要攜帶的字段包括用戶的電話號碼、用戶名和密碼。那么,我們就可以編寫如下的命名為“Isoapboss.wsdl”的文件:

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="soap" xmlns:tns="soap" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://mail.dto.op.web.ngmail.zte.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenc11="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soapenc12="http://www.w3.org/2003/05/soap-encoding" xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">
<wsdl:types>
<xsd:schema attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="soap" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="CreateUserReqt">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="UserPhone" nillable="true" type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="0" name="UserName" nillable="true" type="xsd:string"/>
<xsd:element maxOccurs="1" minOccurs="0" name="Password" nillable="true" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="CreateUserResponse">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="resultcode" type="xsd:int"/>
<xsd:element maxOccurs="1" minOccurs="1" name="description" type="xsd:string"/>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>

<wsdl:message name="CreateUserRequest">
<wsdl:part name="parameters" element="tns:CreateUserReqt"/>
</wsdl:message>

<wsdl:message name="CreateUserResponse">
<wsdl:part name="parameters" element="tns:CreateUserResponse"/>
</wsdl:message>

<wsdl:portType name="IsoapbossPortType">
<wsdl:operation name="CreateUser">
<wsdl:input name="CreateUserRequest" message="tns:CreateUserRequest"/>
<wsdl:output name="CreateUserResponse" message="tns:CreateUserResponse"/>
</wsdl:operation>
</wsdl:portType>

<wsdl:binding name="IsoapbossHttpBinding" type="tns:IsoapbossPortType">
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="CreateUser">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="CreateUserRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="CreateUserResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>

<wsdl:service name="Isoapboss">
<wsdl:port name="IsoapbossHttpPort" binding="tns:IsoapbossHttpBinding">
<wsdlsoap:address location="http://10.10.10.10:9999/soapboss/Isoapboss"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
對於以上文件內容,解釋如下:
第一,開戶時需要包括的消息字段包括UserPhone、UserName和Password,其中UserPhone為必填字段(maxOccurs和minOccurs的值均為1),UserName和Password為選填字段。響應消息包括resultcode(結果碼)和description(結果描述)字段。
第二,文件最后的“http://10.10.10.10:9999/soapboss/Isoapboss”中的“10.10.10.10”和“9999”表示圖3中的SOAP協議轉換模塊所在機器的IP地址和該模塊所綁定的端口號。這兩個值可以在SOAP協議轉換模塊的配置文件中填寫。

2.利用wsdl文件生成SOAP代碼框架
因為我們是在Windows下面編寫的程序,所以將上一步寫好的“Isoapboss.wsdl”文件放到圖2中的“win32”文件夾下,如圖4所示。

圖4 wsdl文件放置位置示意圖
從圖4中可以看到,除了“Isoapboss.wsdl”文件之外,該文件夾下還有“soapcpp2.exe”和“wsdl2h.exe”兩個文件,這兩個文件用於生成代碼框架。
在cmd窗口中依次執行“wsdl2h.exe -c Isoapboss.wsdl”和“soapcpp2.exe Isoapboss.h”命令,如圖5所示。

圖5 代碼框架的生成命令執行示意圖
執行命令之后,便在“win32”文件夾下生成了相關的代碼文件,如圖6所示。

圖6 代碼文件生成之后的文件存放示意圖
我們只需要將圖6中的“.c”和“.h”文件拷貝到我們的代碼工程中就OK了。

3.編寫具體的SOAP消息處理代碼
圖3中的SOAP協議轉換模塊用於接收、解析SOAP消息,然后轉換成內部約定好的消息結構。
該模塊的主要功能有這三個:接收SOAP消息、處理SOAP消息、解析SOAP消息並進行組裝。下面分別來進行說明。
(1)接收SOAP消息
該處理流程的偽代碼如下:

soap_init(&soap); // 初始化soap
m = soap_bind(&soap, IpAdr, Port, BACKLOG); // 綁定IP和端口號

while (!soap_valid_socket(m)) // 循環直至服務套接字合法
{
m = soap_bind(&soap, IpAdr, Port, BACKLOG);
}
……
for (;;) // 用一個死循環來不停地接收SOAP消息
{
s = soap_accept(&soap); // 接收到SOAP消息
if (!soap_valid_socket(s)) // 對錯誤消息的處理
{
……
}
// 將接收到的SOAP消息放入隊列供處理線程處理
EnQueue(data);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(2)處理SOAP消息
該處理流程的偽代碼如下:

for (;;) // 用一個死循環來不停地處理SOAP消息
{
DeQueue(&data); // 將SOAP消息從隊列中取出來處理
……
soap_set_namespaces(tsoap, namespaces); // 設置命名空間
soap_serve(tsoap); // 具體處理SOAP消息的函數
soap_destroy(tsoap); // 處理完成之后,銷毀該SOAP消息
soap_end(tsoap); // 結束本次處理
}
1
2
3
4
5
6
7
8
9
(3)解析SOAP消息並進行組裝
這一步需要我們實現soapStub.h文件中的__ns1__CreateUser函數。
這個流程因為具體的業務不同而不同,在此不再具體說明。

以上三個流程中用的函數均為我們利用wsdl文件生成的SOAP代碼框架中的已經封裝好了的函數。

4.對編寫的代碼進行測試
按照慣例,代碼編寫好之后,我們便要對之進行嚴格的測試。
對於SOAP消息的測試,我們第一步要做的便是在soapUI軟件中新建工程,並將wsdl文件導入進去。例如,我們建立一個名叫TestSoap的工程,如圖7所示。

圖7 新建TestSoap工程示意圖
我們為UserPhone、UserName和Password填上具體的值,然后單擊發消息的按鈕,便開始了正式的對整個程序的測試。測試執行之后的軟件界面如圖8所示。

圖8 測試執行之后的軟件界面
從圖8中我們可以看到,開戶流程執行成功。
為了對程序進行全面的測試,可以設置多組測試用例。

以上便是基於SOAP協議的總體開發流程,具體的編程細節取決於大家所參與的項目的實際情況,但基本的流程都是一致的。

四、總結
本文基於作者的實際開發經歷,對SOAP協議和基於SOAP的開發流程進行了詳細的說明,供從事相關開發的朋友們參考。
在整個開發的過程中,我們要注意以下幾點:
第一,wsdl文件的編寫至關重要,這相當於是內部系統與用戶之間的協議。在編寫代碼之前,大家一定要將協議弄清楚,以免后期修改所帶來的麻煩。
第二,在對代碼進行測試的時候,大家一定要詳細閱讀程序所產生的日志和數據庫中的相關數據,確保每個處理流程的執行都是正確無誤的。
第三,一定要與用戶約定好執行之后的相關結果碼(即resultcode的值),哪些值表示執行成功,哪些值表示執行失敗,都要考慮好。這樣也方便查找程序問題。
第四,對於不同的soapUI的版本,對未填寫的字段的處理會有所不同。有些版本的soapUI會將未填寫的字段當成空指針來處理,大家在編寫代碼的時候要特別注意。

from:https://blog.csdn.net/zhouzhaoxiong1227/article/details/48347547


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM