資料收集
使用天氣調(diào)用的webservice進(jìn)行學(xué)習(xí)
http://www.webxml.com.cn/WebServices/WeatherWebService.asmx
http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?WSDL
1.簡介
最近因?yàn)橐恍┨厥獾男枨笮枰峁┮粋€基于 soap 的 webservice服務(wù),之前沒有經(jīng)驗(yàn),也不知道該怎么做,于是從網(wǎng)上查了很多東西,資料很多,但是大多不夠詳細(xì),后來查到天氣預(yù)報(bào)的webservice服務(wù)說明,算是看懂了一些,寫在這里權(quán)做給大家做一個入門引導(dǎo)好了。
??
2.什么是webservice,什么是soap,什么是 wsdl
- SOAP:Simple Object Access Protocol
- WSDL:Web Services Description Language
一開始接觸這個東西的時候完全把我搞暈了。真的是坑,各種概念。我這里根據(jù)我的采坑經(jīng)驗(yàn)給一些自己的見解,當(dāng)然也要避免誤導(dǎo)參考的人,所以力求準(zhǔn)確吧。
2.1 什么是webservice
??我覺得這個webservice有著狹義和廣義的定義.
??廣義的來說,webservice差不多就是字面意思:web + service,也就是 服務(wù)(service)網(wǎng)絡(luò)(web)化的意思。他力求的是跨語言,跨平臺的,基于web傳輸?shù)倪h(yuǎn)程調(diào)用能力。他沒有強(qiáng)調(diào)遠(yuǎn)程調(diào)用使用什么協(xié)議,所以你可以自由選擇,比如soap 協(xié)議(可與基于http,smtp,等各種傳輸協(xié)議),或者常見的基于http的json化的數(shù)據(jù)傳輸協(xié)議,基于dubbo協(xié)議的dubbo服務(wù)調(diào)用都屬于web service的一種實(shí)現(xiàn)。
??狹義的來說,這個首先聲明,是我參考網(wǎng)上的資料已經(jīng)自身的一些經(jīng)歷的解讀哈。我認(rèn)為大家經(jīng)常談的webservice是指基于soap協(xié)議實(shí)現(xiàn)的遠(yuǎn)程服務(wù)調(diào)用模型。
2.2 什么是soap
??saop定義了數(shù)據(jù)交互中如何傳遞消息的規(guī)則。比如在http中規(guī)定了post請求的傳參方式,在數(shù)據(jù)類型不同的情況下可以使用不同的參數(shù)方式。在form格式下是 key=v&key1=v1 ,同樣soap也是定義這些東西的。
2.3 什么是wsdl
??同樣的,當(dāng)我們用http方式去調(diào)用一個服務(wù)的時候我們只是知道通用的http協(xié)議的傳參方式還是不夠的,我們?nèi)匀恍枰滥繕?biāo)服務(wù)的接口文檔,對了,這就是wsdl,每個服務(wù)都有的接口文檔,在http上可能就是我們手寫的一個wiki文檔,在soap中就是一個用wsdl規(guī)范編寫的wsdl文檔,每個服務(wù)是有能力自動生成這個文檔的。wsdl規(guī)范了這個文檔應(yīng)該怎么寫。
綜上所述:soap可以類比http協(xié)議,wsdl可以類比一個http服務(wù)的接口文檔。
3.結(jié)合比較常用的soap服務(wù)的wsdl文檔來了解一下wsdl
這次用的一個比較常用的文檔就是天氣預(yù)報(bào)的webservice服務(wù)來進(jìn)行學(xué)習(xí)
鏈接:http://www.webxml.com.cn/WebServices/WeatherWebService.asmx
對應(yīng)的是這個文檔的可讀性更強(qiáng)的介紹,他的實(shí)際接口文檔是
http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?WSDL
這篇接口文檔實(shí)際上是有多個接口的描述,當(dāng)然,我們這里只取一個來進(jìn)行描述,取的接口是
getWeatherbyCityName
http://www.webxml.com.cn/WebServices/WeatherWebService.asmx?op=getWeatherbyCityName
這個頁面有詳細(xì)的請求體和返回結(jié)果,很具體。下面我們就從他的實(shí)際接口文檔wsdl中來分析一下都有什么東西。
我們知道wsdl文檔包含了這么幾個部分
<definitions>
<types>
definition of types........
數(shù)據(jù)類型定義的容器,它使用某種類型系統(tǒng)(一般地使用XML Schema中的類型系統(tǒng))
</types>
<message>
definition of a message....
通信消息的數(shù)據(jù)結(jié)構(gòu)的抽象類型化定義。使用Types所定義的類型來定義整個消息的數(shù)據(jù)結(jié)構(gòu)。
</message>
<portType>
definition of a port.......
對于某個訪問入口點(diǎn)類型所支持的操作的抽象集合,這些操作可以由一個或多個服務(wù)訪問點(diǎn)來支持。
</portType>
<binding>
definition of a binding....
特定端口類型的具體協(xié)議和數(shù)據(jù)格式規(guī)范的綁定。
</binding>
<service>
相關(guān)服務(wù)訪問點(diǎn)的集合。
</servie>
</definitions>
下面我們使用getWeatherbyCityName這個接口在總的xml對應(yīng)的部分做說明,將xml提取出來如下
還請學(xué)習(xí)下面的文檔的時候參考 對應(yīng)的可視化文檔
進(jìn)行對比
<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://WebXml.com.cn/"
xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://WebXml.com.cn/">
<!-- types元素-->
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://WebXml.com.cn/">
<!-- 可以看到,types 定義的是數(shù)據(jù)類型,可以在message元素中進(jìn)行引用,他的存在形式可能是type也可能是element-->
<s:complexType name="ArrayOfString">
<s:sequence>
<s:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="s:string"/>
</s:sequence>
</s:complexType>
<s:element name="getWeatherbyCityName">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="theCityName" type="s:string"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="getWeatherbyCityNameResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="0" maxOccurs="1" name="getWeatherbyCityNameResult"
type="tns:ArrayOfString"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="ArrayOfString" nillable="true" type="tns:ArrayOfString"/>
<s:element name="DataSet" nillable="true">
<s:complexType>
<s:sequence>
<s:element ref="s:schema"/>
<s:any/>
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
<!-- message元素-->
message 用來定義每個soap服務(wù)的入?yún)⒑统鰠?,包括參?shù)名,參數(shù)類型信息。當(dāng)引用了types 當(dāng)中定義的element元素的時候,name只是有占位意義,并不具備實(shí)際的意義
當(dāng)引用了types中定義的 type型元素的時候,name 是有意義的,這里的每個message定義并不是針對某個接口的,而是作為基礎(chǔ)元素,在portType中描述接口的時候使用。
<wsdl:message name="getWeatherbyCityNameSoapIn">
name只是有占位意義,并不具備實(shí)際的意義
<wsdl:part name="parameters" element="tns:getWeatherbyCityName"/>
</wsdl:message>
<wsdl:message name="getWeatherbyCityNameSoapOut">
<wsdl:part name="parameters" element="tns:getWeatherbyCityNameResponse"/>
</wsdl:message>
<wsdl:message name="getWeatherbyCityNameHttpGetIn">
name 是有意義的
<wsdl:part name="theCityName" type="s:string"/>
</wsdl:message>
<wsdl:message name="getWeatherbyCityNameHttpGetOut">
<wsdl:part name="Body" element="tns:ArrayOfString"/>
</wsdl:message>
<wsdl:message name="getWeatherbyCityNameHttpPostIn">
name 是有意義的
<wsdl:part name="theCityName" type="s:string"/>
</wsdl:message>
<wsdl:message name="getWeatherbyCityNameHttpPostOut">
<wsdl:part name="Body" element="tns:ArrayOfString"/>
</wsdl:message>
<!-- portType 元素-->
定義了一個接口的入?yún)⒑统鰠?每個portType元素實(shí)際上對應(yīng)了一個接口,就像springMVC當(dāng)中controller當(dāng)中定義的一個有@RequestMapping注解的方法一樣,他描述了這個方法的入?yún)⒑统鰠ⅰ? <wsdl:portType name="WeatherWebServiceSoap">
<wsdl:operation name="getWeatherbyCityName">
<wsdl:input message="tns:getWeatherbyCityNameSoapIn"/>
<wsdl:output message="tns:getWeatherbyCityNameSoapOut"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:portType name="WeatherWebServiceHttpGet">
<wsdl:operation name="getWeatherbyCityName">
<wsdl:input message="tns:getWeatherbyCityNameHttpGetIn"/>
<wsdl:output message="tns:getWeatherbyCityNameHttpGetOut"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:portType name="WeatherWebServiceHttpPost">
<wsdl:operation name="getWeatherbyCityName">
<wsdl:documentation xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">...</wsdl:documentation>
<wsdl:input message="tns:getWeatherbyCityNameHttpPostIn"/>
<wsdl:output message="tns:getWeatherbyCityNameHttpPostOut"/>
</wsdl:operation>
</wsdl:portType>
<!-- bingding元素 -->
仔細(xì)觀察下面的配置的話可以發(fā)現(xiàn),這幾個bingding元素的差異是很大的。
在bingding的第二行說明的是 該bingding使用的協(xié)議,是 soap或者soap12 或者是 http-get 或者是 http-post
這里的 bingding 元素對應(yīng)的type屬性標(biāo)識了對應(yīng)的portType元素
這里的operation對應(yīng)了上面對應(yīng)bingding元素中的operation,同時,這里可以歲輸入輸出做一些處理,比如urlEncoded。use="literal"表示不做特殊處理。
<wsdl:binding name="WeatherWebServiceSoap" type="tns:WeatherWebServiceSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getWeatherbyCityName">
<soap:operation soapAction="http://WebXml.com.cn/getWeatherbyCityName" style="document"/>
<wsdl:input>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="WeatherWebServiceSoap12" type="tns:WeatherWebServiceSoap">
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="getWeatherbyCityName">
<soap12:operation soapAction="http://WebXml.com.cn/getWeatherbyCityName" style="document"/>
<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="WeatherWebServiceHttpGet" type="tns:WeatherWebServiceHttpGet">
<http:binding verb="GET"/>
<wsdl:operation name="getWeatherbyCityName">
在http類型中還會增加具體的location信息,這個在對應(yīng)的http請求里面是可以區(qū)分出來的,比如,
soap對應(yīng)的請求是 POST /WebServices/WeatherWebService.asmx HTTP/1.1
http-get對應(yīng)的請求是 GET /WebServices/WeatherWebService.asmx/getWeatherbyCityName?theCityName=string HTTP/1.1
<http:operation location="/getWeatherbyCityName"/>
<wsdl:input>
<http:urlEncoded/>
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:binding name="WeatherWebServiceHttpPost" type="tns:WeatherWebServiceHttpPost">
<http:binding verb="POST"/>
<wsdl:operation name="getWeatherbyCityName">
<http:operation location="/getWeatherbyCityName"/>
<wsdl:input>
<mime:content type="application/x-www-form-urlencoded"/>
</wsdl:input>
<wsdl:output>
<mime:mimeXml part="Body"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<!-- service 元素-->
這里定義的是每個方法具體的訪問地址,指向了每個bingding具體綁定的服務(wù)地址。
<wsdl:service name="WeatherWebService">
<wsdl:port name="WeatherWebServiceSoap" binding="tns:WeatherWebServiceSoap">
<soap:address location="http://www.webxml.com.cn/WebServices/WeatherWebService.asmx"/>
</wsdl:port>
<wsdl:port name="WeatherWebServiceSoap12" binding="tns:WeatherWebServiceSoap12">
<soap12:address location="http://www.webxml.com.cn/WebServices/WeatherWebService.asmx"/>
</wsdl:port>
<wsdl:port name="WeatherWebServiceHttpGet" binding="tns:WeatherWebServiceHttpGet">
<http:address location="http://www.webxml.com.cn/WebServices/WeatherWebService.asmx"/>
</wsdl:port>
<wsdl:port name="WeatherWebServiceHttpPost" binding="tns:WeatherWebServiceHttpPost">
<http:address location="http://www.webxml.com.cn/WebServices/WeatherWebService.asmx"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
4. 干脆把對應(yīng)的請求信息也摘錄下來好了
截取自 這里
getWeatherbyCityName
4.1 SOAP 1.1
以下是 SOAP 1.2 請求和響應(yīng)示例。所顯示的占位符需替換為實(shí)際值。
POST /WebServices/WeatherWebService.asmx HTTP/1.1
Host: www.webxml.com.cn
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://WebXml.com.cn/getWeatherbyCityName"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<getWeatherbyCityName xmlns="http://WebXml.com.cn/">
<theCityName>string</theCityName>
</getWeatherbyCityName>
</soap:Body>
</soap:Envelope>
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<getWeatherbyCityNameResponse xmlns="http://WebXml.com.cn/">
<getWeatherbyCityNameResult>
<string>string</string>
<string>string</string>
</getWeatherbyCityNameResult>
</getWeatherbyCityNameResponse>
</soap:Body>
</soap:Envelope>
4.2 SOAP 1.2
以下是 SOAP 1.2 請求和響應(yīng)示例。所顯示的占位符需替換為實(shí)際值。
POST /WebServices/WeatherWebService.asmx HTTP/1.1
Host: www.webxml.com.cn
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<getWeatherbyCityName xmlns="http://WebXml.com.cn/">
<theCityName>string</theCityName>
</getWeatherbyCityName>
</soap12:Body>
</soap12:Envelope>
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
<soap12:Body>
<getWeatherbyCityNameResponse xmlns="http://WebXml.com.cn/">
<getWeatherbyCityNameResult>
<string>string</string>
<string>string</string>
</getWeatherbyCityNameResult>
</getWeatherbyCityNameResponse>
</soap12:Body>
</soap12:Envelope>
4.3 HTTP GET
以下是 HTTP GET 請求和響應(yīng)示例。所顯示的占位符需替換為實(shí)際值。
GET /WebServices/WeatherWebService.asmx/getWeatherbyCityName?theCityName=string HTTP/1.1
Host: www.webxml.com.cn
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfString xmlns="http://WebXml.com.cn/">
<string>string</string>
<string>string</string>
</ArrayOfString>
4.4 HTTP POST
以下是 HTTP POST 請求和響應(yīng)示例。所顯示的占位符需替換為實(shí)際值。
POST /WebServices/WeatherWebService.asmx/getWeatherbyCityName HTTP/1.1
Host: www.webxml.com.cn
Content-Type: application/x-www-form-urlencoded
Content-Length: length
theCityName=string
HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfString xmlns="http://WebXml.com.cn/">
<string>string</string>
<string>string</string>
</ArrayOfString>