最近關注一些 Application Server 開發的問題,試用了一下 gSoap。
gSoap 實際上一個編譯器,包含兩個工具:
wsdl2h 用於將 WSDL 文件轉換成頭文件
soapcpp2 用於將頭文件轉換成編寫 SOAP 服務器和客戶端所需要的文件
還是從最簡單的 HelloWorld 程序來認識 gSoap
下面的是實現兩個整數相加的 SOAP 程序
//gsoap ns service name: add
//gsoap ns service namespace: http://192.168.88.1/add.wsdl
//gsoap ns service location: http://192.168.88.1
//gsoap ns service executable: add.cgi
//gsoap ns service encoding: encoded
//gsoap ns schema namespace: urn:add
int ns__add( int num1, int num2, int* sum );
需要執行的過程是:
soapcpp2.exe add.h
然後編寫服務器和客戶端的代碼。
爲了進一步瞭解 SOAP 底層的過程,可以截取數據包進行查看
客戶端發生的信息:
POST / HTTP/1.0
Host: 192.168.88.1
User-Agent: gSOAP/2.1
Content-Type: text/xml; charset=utf-8
Content-Length: 438
SOAPAction: ""
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ns="urn:add" xmlns="urn:add" SOAP-ENV:encodingStyle="encoded">
<SOAP-ENV:Body>
<ns:add>
<num1>2</num1>
<num2>5</num2>
</ns:add>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
服務器的響應信息:
HTTP/1.0 200 OK
Server: gSOAP/2.1
Content-Type: text/xml; charset=utf-8
Content-Length: 438
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:ns="urn:add" xmlns="urn:add" SOAP-ENV:encodingStyle="encoded">
<SOAP-ENV:Body><ns:addResponse>
<sum>7</sum>
</ns:addResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
得到實際的 HTTP 信息之後,直接利用 python 可以很容易寫出客戶端的代碼
import urllib2
import sys, httplib
def SendRtx(num1, num2):
SENDTPL = /
'''<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns="urn:add" xmlns="urn:add" SOAP-ENV:encodingStyle="encoded">
<SOAP-ENV:Body>
<ns:add>
<num1>%s</num1>
<num2>%s</num2>
</ns:add>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>'''
SoapMessage = SENDTPL % (num1,num2)
webservice = httplib.HTTP("192.168.88.1", 4567)
webservice.putrequest("POST", "/")
webservice.putheader("Host", "192.168.88.1")
webservice.putheader("User-Agent", "Python Post")
webservice.putheader("Content-type", "text/xml; charset=/"UTF-8/"")
webservice.putheader("Content-length", "%d" % len(SoapMessage))
webservice.putheader("SOAPAction", "")
webservice.endheaders()
webservice.send(SoapMessage)
# get the response
statuscode, statusmessage, header = webservice.getreply()
print "Response: ", statuscode, statusmessage
print "headers: ", header
print webservice.getfile().read()
SendRtx(1, 1)
之後嘗試利用 jQuery 編寫 ajax 代碼來訪問 SOAP 服務,悲劇的是居然有兼容性問題,只有 IE 能夠正常調用。
像 firefox 和 chrome 都會發送一些糟糕的 Internal Server Error。