藍字爲關鍵字,等號=後面爲關鍵字值。web
1、介紹數組
咱們用的webservice是根據gsoap編譯工具來實現,gSOAP的編譯器可以自動的將用戶定義的本地化的C或C++數據類型轉變爲符合XML語法的數據結構。同時gSOAP可以根據標準化的wsdl(徹底符合wsdl書寫格式)文件來生成本地須要的C或C++源代碼以肯定發送接收XML文件的格式;數據結構
2、使用說明架構
當前咱們用到的gSOAP版本是2.8.3,下面是生成源碼的wsdl文件;若是想要生成C代碼,則在生成源碼時指定-c選項;例如wsdl文件名稱爲host.wsdl,依據如下兩步生成源碼:app
wsdl2h –c –s –o host.h host.wsdl(具體使用能夠查看幫助,依據wsdl文件生成c頭文件)異步
soapcpp2 –c host.h(依據c指定的頭文件生成c源碼)ide
一個簡單host.wsdl文件:(/**/註釋欄爲wsdl說明)函數
------------------------------------------------華麗的分割線-------------------------------------工具
1 <?xml version="1.0" encoding="UTF-8"?>/*指定版本及編碼格式*/ 2 /*definitions是wsdl根元素,下面一般包含如下元素,即types/ message/ portType/ operation/ binding/ service */ 3 <definitions name="MessageInfo" 4 xmlns:tns="http://messageinfo.com" 5 xmlns:xsd="http://www.w3.org/2001/XMLSchema" 6 xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 7 xmlns="http://schemas.xmlsoap.org/wsdl/" 8 targetNamespace="http://messageinfo.com"> 9 /*types是數據類型定義的元素 其應用主要是schema定義格式類型*/ 10 <types> 11 <schema targetNamespace="http://messageinfo.com" 12 xmlns="http://www.w3.org/2001/XMLSchema"> 13 <complexType name="StatisticsRequest"> 14 <sequence> 15 <element name="request" type="string"/> 16 </sequence> 17 </complexType> 18 <complexType name="StatisticsResponse"> 19 <sequence> 20 <element name="AllPaketsnum" type="unsignedLong"/> 21 <element name="WormTypenum" type="unsignedLong"/> 22 <element name="Reverse1" type="string"/> 23 </sequence> 24 </complexType> 25 </schema> 26 </types> 27 /* message描述通訊消息的數據結構的抽象化類型定義 */ 28 <message name="GetMessageRequest"> 29 <part name="Operateget" type="tns:StatisticsRequest"/> 30 </message> 31 <message name="GetMessageResponse"> 32 <part name="Operateput" type="tns:StatisticsResponse"/> 33 </message> 34 /* portType描述服務和服務的方法 */ 35 <portType name="MessagePortType"> 36 <operation name="GetMessageRepq"> 37 <input message="tns:GetMessageRequest"/> 38 <output message="tns:GetMessageResponse"/> 39 </operation> 40 </portType> 41 /* 描述通訊協議,注意rpc document literal encoded各類匹配組合使用*/ 42 <binding name="MessageSoapBinding" type="tns:MessagePortType"> 43 <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> 44 <operation name="GetMessageRepq"> 45 <soap:operation style="rpc" soapAction=""/> 46 <input> 47 <soap:body use="literal" namespace="http://messageinfo.com"/> 48 </input> 49 <output> 50 <soap:body use="literal" namespace="http://messageinfo.com"/> 51 </output> 52 </operation> 53 </binding> 54 /*service描述webservice訪問點的集合*/ 55 <service name="MessageService"> 56 <documentation>Stat Message Service Topsec Ips provide</documentation> 57 <port name="MessageSerPort" binding="tns:MessageSoapBinding"> 58 <soap:address location="http://localhost:80"/> 59 </port> 60 </service> 61 62 </definitions>
3、元素介紹性能
關於xml格式問題,參考xml文檔,wsdl具體應用分爲下面幾類:
下面將對每一個元素進行詳細說明:
1. Definitions
定義了文檔中用到的各個xml元素的namespace縮寫,
也界定了本文檔本身的 targetNamespace="http://www.jsoso.com/wstest",
這意味着其它的XML要引用當前XML中的元素時,要聲明這個namespace。
注意xmlns:tns="http://www.jsoso.com/wstest"這個聲明,它標示了使用tns這個前綴 指向自身的命名空間
1 <definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 2 xmlns:tns:="http://www.jsoso.com/wstest" 3 xmlns:xsd="http://www.w3.org/2001/XMLSchema" 4 xmlns="http://schemas.xmlsoap.org/wsdl/" 5 targetNamesapce="http://www.jsoso.com/wstest" 6 name="Example"> 7 ...... 8 </definitions>
2. types
<types>標籤訂義了當前的WSDL文檔用到的數據類型。
要說明的是,爲了最大程度的平臺中立性,WSDL 使用 XML Schema 語法來定義數據類型。
這些數據類型用來定義web service方法的參數和返回值。對於通用的原生數據類型如:
integer , boolean , char , float等,
在W3C的標準文檔http://www.w3.org/2001/XMLSchema中已經作了定義。
這裏咱們要引入的schema定義 schemaLocation="http://localhost:8080/hello?xsd=1"是咱們自定義的對象類型。
(自定義對象類型地址不存在wsdl會怎樣處理?)
1 <types> 2 <xsd:schema> 3 <sxd:import namespace="http://www.jsoso.com/wstest" 4 schemaLocation="http://localhost:8080/hello?xsd=1"> 5 </xsd:import> 6 </xsd:schema> 7 </types>
3. message就是用來soap消息的
<message>元素定義了web service函數的參數。
<message>元素中的每一個<part>子元素都和某個參數相符。
輸入參數在<message>元素中定義,與輸出參數相隔離,
輸出參數有本身的<message>元素。
兼做輸入、輸出的參數在輸入輸出的<message>元素中有它們相應的<part>元素。
輸出 <message>元素以"Response"結尾,對Java而言方法得返回值就對應一個輸出的<message>。
每一個<part>元素都有名字和類 型屬性,就像函數的參數有參數名和參數類型。
1 <message name="sayHello"> 2 <part name="person" type="tns:person"></part> 3 <part name="arg1" type="xsd:string"></part> 4 </message> 5 6 <message name="sayHelloResponse"> 7 <part name="personList" type="tns:personArray"></part> 8 </message> 9 <message name="HelloException"> 10 <part name="fault" element="tns:HelloException"></part> 11 </message>
4. portType
指明服務的接口名稱。
在<operation>元素中,name屬性表示服務方法名,
parameterOrder屬性表示方法的參數順序,
使用空格符分割多個參數,如:「parameterOrder="person arg1」。
<operation>元素的子標籤<input>表示輸入參數說明,它引用<message>標籤中的輸入參數。
<output>表示輸出參數說明,它引用<message>標籤中的輸出參數。
<fault>標籤在Java方法中的特別用來表示異常(其它語言有對應的錯誤處理機制),
它引用<message>標籤中的錯誤參數。
1 <portType name="Example"> 2 3 <operation name="toSayHello" parameterOrder="userName"> 4 <input message="tns:toSayHello"></input> 5 <output message="tns:toSayHelloResponse"></output> 6 </operation> 7 <operation name="sayHello" parameterOrder="person arg1"> 8 <input message="tns:sayHello"></input> 9 <output message="tns:sayHelloResponse"></output> 10 <fault message="tns:HelloException" name="HelloException"></fault> 11 </operation> 12 </portType>
5. binding
指定消息傳遞的格式,<binding>標籤是完整描述協議、序列化和編碼的地方,
<types>,<message>和<portType>標籤處理抽象的數據內容,而<binding>標籤是處理數據傳輸的物理實現。
<binding>標籤把前三部分的抽象定義具體化。
style="rpc":消息的展示形式;有兩個值,rpc和content
use="literal":消息應該以什麼樣的形式來傳遞;有兩個值,literal和encodes。但目前都是用literal。
<operation>子標籤將portType中定義的operation同SOAP的請求綁定,
定義了操做名稱soapAction,輸出輸入參數和異常的編碼方式及命名空間。
1 <binding name="ExamplePortBinding" type="tns:Example"> 2 <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="rpc"></soap:binding> 3 <operation name="toSayHello"> 4 <soap:operation soapAction="sayHello"></soap:operation> 5 <input> 6 <soap:body use="literal" namespace="http://www.jsoso.com/wstest"></soap:body> 7 </input> 8 <output> 9 <soap:body use="literal" namespace="http://www.jsoso.com/wstest"></soap:body> 10 </output> 11 </operation> 12 <operation name="sayHello"> 13 <soap:operation soapAction="sayHello"></soap:operation> 14 <input> 15 <soap:body use="literal" namespace="http://www.jsoso.com/wstest"></soap:body> 16 </input> 17 <output> 18 <soap:body use="literal" namespace="http://www.jsoso.com/wstest"></soap:body> 19 </output> 20 <fault name="HelloException"> 21 <soap:fault name="HelloException" use="literal"></soap:fault> 22 </fault> 23 </operation> 24 </binding>
WSDL 綁定樣式由兩個屬性組合而成:style、use;style能夠是RPC/Document,use能夠是Encoded/Literal;下面解釋下這4個名詞的意思:
RPC 樣式
RPC樣式指定<soap:body> 元素包含一個將被調用的web方法的名稱的元素(wrapper element(封裝元素))。這個元素依次爲該方法的每一個參數還有返回值做了記錄。
Document 樣式
若是是document 樣式,就沒有像在RPC樣式中的wrapper元素。轉而代之的是消息片段直接出如今<soap:body>元素之下。沒有任何SOAP格式化規則規定<soap:body>元素下能包含什麼;它包含的是一個發送者和接收者都達成一致的XML文檔。
Encoded 編碼
若是use的值是」encoded」, 則每一個消息片斷將使用類型屬性來引用抽象類型。經過應用由 encodingStyle 屬性所指定的編碼樣式,可以使用這些抽象類型生成具體的消息。最經常使用到的SOAP編碼樣式是在SOAP1.1中定義的一組序列化規則,它說明了對象、結構、數組和圖形對象應該如何序列化。一般,在應用程序中使用SOAP編碼着重於遠程進程調用和之後適合使用RPC消息樣式。
Literal 文字
若是use 的值是」Literal」, 則每一個片斷使用 element 屬性(對於簡單片斷)或 type 屬性(對於複合片斷)來引用具體架構,例如,數據根據指定的架構來序列化,這架構一般使用W3C XML架構來表述。
根據不一樣的組合,造成了四種綁定模型;另外,還有一種用Document模擬RPC樣式的包裝組合也很常見;
1.RPC/Encoded
2.RPC/Literal
3.Document/Encoded
4.Document/Literal
5.Document/Literal Wrapped
對於以上5種組合方式,因爲Document/Encoded不被現有平臺所支持,在實際中應用不多,因此這裏就暫時不討論該種組合;對於剩下的4種組合,咱們結合一個表格和實例來對比下各自的優劣狀況;
Binding Type Advantage/DisAdvantage
RPC/Encoded 優勢:
1.WSDL文件的定義遵循直觀和衆所周知的遠程進程調用的溝通模式。
2.操做名顯示在消息中,所以接收者很容易就把消息分派給它的實現。
3.若是你正在你的服務中使用數據圖形或者多態,這是唯一能使用的樣式。
缺點:
1.SOAP消息包含的類型編碼信息就如xsi:type="xsd:int",這些就是一種開銷。
2.一般驗證SOAP消息是很困難的,由於在WSDL Shcema中沒有描述。
3.RPC樣式引發了一種在服務提供者和客戶之間的緊密耦合,任何對接口的更改都會致使服務和客戶間聯繫的中斷。
4.不被WSI一致性標準所支持。RPC/
Literal 優勢:
1.WSDL定義仍然像RPC/Encoded樣式同樣簡單直接。
2.操做名仍然出如今SOAP消息中。
3.把類型編碼從消息中排除了,所以提高了吞吐性能。
缺點:
1.服務和客戶之間仍然有緊密耦合。
2.仍然難以用SOAP消息來驗證傳輸的數據。
3.它也不被WSI一致性標準所支持。
Document/Litaral 優勢:
1.在SOAP消息中沒有類型編碼信息。
2.你總能用任何XML驗證器來驗證消息,在soap體中任何東西都在schema中有定義。
3.使用document樣式,規則不是那麼嚴格,還有對XML Schema進行加強和更改時不會破壞接口。
4.若是使用某特殊序列進行多進程調用,Document 樣式能夠保持應用程序的狀態。
5.Document樣式更加適合異步處理。
6.許多document-messaging服務可以選擇文檔的DOM和SAX 兩種處理方式的其中一種,結果就是能最小化在內存中的處理。
缺點:
1.WSDL定義變得更加複雜。
2.在SOAP消息中的操做名沒有了,沒有了名稱,把消息分派給它的實現方法就變得困難或不可能了。
Document/Literal
Wrapped 優勢:
1.包含了全部Document/Literal樣式的優勢。
2.操做名出如今SOAP消息中。
缺點:
1.即便WSDL定義變得更加複雜,但仍然有很多缺點。
2.若是你在web服務中重載了操做,你就不能使用該樣式。
6. service
service是一套<port>元素。
在一一對應形式下,每一個<port>元素都和一個location關聯。
若是同一個<binding>有多個<port>元素與之關聯,
可使用額外的URL地址做爲替換。
一個WSDL文檔中能夠有多個<service>元素,
並且多個<service>元素十分有用,其中之一就是能夠根據目標URL來組織端口。
在一個 WSDL文檔中,<service>的name屬性用來區分不一樣的service。
在同一個service中,不一樣端口,使用端口的"name"屬性區 分。
1 <service name="Example"> 2 <port name="ExamplePort" binding="tns:ExamplePortBinding"> 3 <soap:address location="http://localhost:8080/hello"></soap:address> 4 </port> 5 </service>
4、說明
這裏編寫webservice.c文件能夠將須要的代碼程序生成so(動態庫),方便隨時調用(具體使用說明參考gsoap)
1 # Makefile for make libwebservice.so 2 3 DIRS = 4 SHARE = -shared -lc 5 USER_LIBS = -lssl -ldl -lcrypto 6 MODULES = libwebservice.so 7 MODULES_OBJS = soapC.o soapServer.o stdsoap2.o webservice.o 8 9 CFLAGS = -Wall -DWITH_OPENSSL 10 11 all: $(MODULES) 12 13 $(MODULES): $(MODULES_OBJS) 14 cc $(USER_LIBS) $(CFLAGS) ${SHARE} -o ${MODULES} $^ 15 strip ${MODULES} 16 17 clean: 18 rm *.o *.a *.so -rf 19 for filename in $(DIRS); do \ 20 ( cd $$filename; $(MAKE) $@ ); \ 21 done
瞭解了整個結構,對傳輸類型及方式能夠很好的把控,也能夠將整個結構體進行傳輸及使用。