注:下文是關于WebService的一個概念和總結,其中的例子來自
http://www.box.net/shared/cyg98xgz78 。 如果您對WebService已經熟悉就不用浪費時間了。
一.什么是Web服務?
Web服務是網絡化應用程序的一種,我們可以將Web服務看成一種函數調用,只不過這個函數的實體存在于某個服務器上,而調用在客戶端進行。Web服務的思想很簡單,即服務器通過網絡提供Web服務,其它程序可以將由Web服務器封裝的功能無縫的集成到自己的程序中去。Web服務是跨平臺跨語言的,它可以由多種語言創建,也可以由多種語言使用。WebService定義了一套標準的調用過程:服務器端使用WSDL來向外界描述它所提供的服務,客戶端與服務器端的交互采用SOAP協議。
二.Web服務有什么益處?
處于這個信息化高度發展的世界,每個軟件系統都勢必要和別的軟件系統進行交互,它們可能由不同語言編寫運行在不同的服務器上,相互間的調用是一個很大的難題。Web服務就是為解決這些問題而誕生的,它的語言平臺無關性可以和任一平臺或語言的軟件進行交互,這樣,Web服務就可以像一座橋梁,可以連通信息化世界中的孤島。
三.SOAP協議。
在Web服務中,服務器和客戶機需要傳遞接收消息,這就需要對傳輸的數據格式采取一定的約定措施,這個約定就是SOAP協議,它的全稱是簡單對象訪問協議(Simple Object Access Protocl)。SOAP是基于XML的消息包裝器,它既包括客戶端送給服務器端希望調用的類和方法的一種消息格式,也包括服務器返回數據的消息格式。有個這個協議,服務器和客戶機就能明白對方想干什么。SOAP消息一般基于HTTP來傳輸,也可以基于其他協議。
下面是一個客戶端向服務器發送的SOAP消息例子:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<ns1:getServerPublicKey xmlns:ns1="http://heyang.com">
</ns1:getServerPublicKey>
</soap:Body>
</soap:Envelope>
客戶機向服務器端發送消息時,</soap:Body>中的XML包含要調用的方法和參數,如上述的getServerPublicKey。
下面是服務器反饋給客戶機的SOAP消息例子:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soap:Body>
<ns1:getServerPublicKeyResponse xmlns:ns1="hello.XFire"> <ns1:out>MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDkSpbrSfBIIu+f4mMr7Ie2JdWCBEmlZ1mcoZ0UTNMGaVwexfRax+HC/uusXvkkdoUGYjMaiMycRsQtSOLsfKjOVY/8zBLs0tAOEVelg6MyiF3DV7PVgGEq0dpXJCz0MWFY34a1YJMbPfvPa+VpZaIFbzICUPRhVdBYPAboXthFyQIDAQAB
</ns1:out>
</ns1:getServerPublicKeyResponse>
</soap:Body>
</soap:Envelope>
當服務器端送回消息時,</soap:Body>中包含調用的結果,它可以是單個值,也可以是含有多個值的復雜數據類型。如上面的<ns1:out>中的節點值。
另:在調試WebService程序,想要查看SOAP消息時,可以使用Apache的TCPMon工具,具體使用方法請看
http://www.tkk7.com/heyang/archive/2010/12/10/340294.html.
四.服務器端收到SOAP消息后的動作
以XFire為例,當一個來自客戶端的SOPA請求送達WebService服務端時,它會先送到一個Servlet(XFireConfigurableServlet)中(請參看web.xml中的配置),然后開始解析SOAP消息,再根據配置文件services.xml找到接口com.heyang.IService和具體的實現類com.heyang.ServiceImpl中的方法,調用函數產生結果,然后再包裝成SOAP消息返回。Axis的做法也是類似的。
五.WSDL
我們現在可以想到Web服務是一個對象,含有一個或多個方法。如何對一個WebService服務器能提供的方法進行說明呢?這里就要用到WSDL(Web Service Description Language),它定義了Web服務提供的可供操作的函數,具體如下:
<?xml version="1.0" encoding="UTF-8" ?>
- <wsdl:definitions targetNamespace="hello.XFire" xmlns:soapenc12="http://www.w3.org/2003/05/soap-encoding" xmlns:tns="hello.XFire" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap11="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc11="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
- <wsdl:types>
- <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="hello.XFire">
- <xsd:element name="getServerPublicKey">
<xsd:complexType />
</xsd:element>
- <xsd:element name="getServerPublicKeyResponse">
- <xsd:complexType>
- <xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="out" nillable="true" type="xsd:base64Binary" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
- <xsd:element name="getResonse">
- <xsd:complexType>
- <xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="in0" nillable="true" type="xsd:base64Binary" />
<xsd:element maxOccurs="1" minOccurs="1" name="in1" nillable="true" type="xsd:base64Binary" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
- <xsd:element name="getResonseResponse">
- <xsd:complexType>
- <xsd:sequence>
<xsd:element maxOccurs="1" minOccurs="1" name="out" nillable="true" type="xsd:base64Binary" />
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
</wsdl:types>
- <wsdl:message name="getServerPublicKeyRequest">
<wsdl:part name="parameters" element="tns:getServerPublicKey" />
</wsdl:message>
- <wsdl:message name="getResonseResponse">
<wsdl:part name="parameters" element="tns:getResonseResponse" />
</wsdl:message>
- <wsdl:message name="getServerPublicKeyResponse">
<wsdl:part name="parameters" element="tns:getServerPublicKeyResponse" />
</wsdl:message>
- <wsdl:message name="getResonseRequest">
<wsdl:part name="parameters" element="tns:getResonse" />
</wsdl:message>
- <wsdl:portType name="helloPortType">
- <wsdl:operation name="getServerPublicKey">
<wsdl:input name="getServerPublicKeyRequest" message="tns:getServerPublicKeyRequest" />
<wsdl:output name="getServerPublicKeyResponse" message="tns:getServerPublicKeyResponse" />
</wsdl:operation>
- <wsdl:operation name="getResonse">
<wsdl:input name="getResonseRequest" message="tns:getResonseRequest" />
<wsdl:output name="getResonseResponse" message="tns:getResonseResponse" />
</wsdl:operation>
</wsdl:portType>
- <wsdl:binding name="helloHttpBinding" type="tns:helloPortType">
<wsdlsoap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
- <wsdl:operation name="getServerPublicKey">
<wsdlsoap:operation soapAction="" />
- <wsdl:input name="getServerPublicKeyRequest">
<wsdlsoap:body use="literal" />
</wsdl:input>
- <wsdl:output name="getServerPublicKeyResponse">
<wsdlsoap:body use="literal" />
</wsdl:output>
</wsdl:operation>
- <wsdl:operation name="getResonse">
<wsdlsoap:operation soapAction="" />
- <wsdl:input name="getResonseRequest">
<wsdlsoap:body use="literal" />
</wsdl:input>
- <wsdl:output name="getResonseResponse">
<wsdlsoap:body use="literal" />
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
- <wsdl:service name="hello">
- <wsdl:port name="helloHttpPort" binding="tns:helloHttpBinding">
<wsdlsoap:address location="http://localhost:8080/XfireSample/services/hello" />
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
以上內容在瀏覽器中輸入http://localhost:8080/XfireSample/services/hello?wsdl 可以看到。
WSDL本身比較復雜,它主要給程序看的,利用當前大多數的Web服務工具可以生成它,而無需手工編寫它。
WSDL的主要目的在于將自己的Web服務的所有相關內容如提供服務的傳輸方式,服務方法接口,接口參數,服務路徑等,生成相應的完全的文檔,發布給使用者。使用者可以通過這個WSDL文檔,創建相應的SOAP請求消息,通過HTTP傳遞給Web服務提供者;Web服務提供者在完成請求服務后,將SOAP返回消息傳回給請求者,服務請求者再根據WSDL文檔將SOAP返回消息解析成程序能夠理解的內容。
六.UDDI
UDDI是Universal Description Discovery and Intergretion的縮寫,是一種創建注冊服務的規范,以便大家將自己的Web Service進行注冊發布供使用者查找。
當服務提供者想將自己的Web Service發布,以便外部能找到其服務時,那么服務提供這可以將自己的Web Service注冊到相應的UDDI商用注冊網站。
UDDI并非一個必須的Web Service組件,服務方完全可以不進行UDDI的注冊。因為WSDL文件中已經給出了Web Service的地址URI,外部可以通過它進行相應的Web Service調用.
七.消息服務與WebService的比較
在概念上,Web Service和消息服務它們都是傳輸數據到別的組件,都是使應用程序之間可以進行異步通信。
消息處理和Web Service是互補的技術,消息服務明確是一項為企業內部而不是為商業領域內的應用程序提供通信的技術,使用消息處理,企業必須與共用的傳輸格式達成一致,在定義應用程序之間傳遞的數據方面,消息具有更多的靈活性,另外,Web Service缺乏一個定義好的機制,用于確保SOAP傳輸和事務處理,這些是消息服務已經定義好和成熟的部分。
Web Service,是松散耦合的組件,應用程序發送請求給它進行處理和數據服務,結果返回給應用程序繼續處理,傳輸機制是Simple Object Access Protocol(簡單對象訪問協議,SOAP),Web Service通過SOAP能有效的通過HTTP協議發送XML文檔。Web Service具有公開性,具有快速推進的標準和大量出版物與技術文檔。Web Service有潛力來連接不同的應用程序組件,把軟件定義成服務而不是產品。如果應用程序是新建的,則Web Service更為合理。
八.使用Axis的WebService實現。
以上文章是針對XFire的WS實現,如果要用Axis的實現,可以參考這里
http://www.tkk7.com/heyang/archive/2009/10/10/297729.html 或
http://www.tkk7.com/heyang/archive/2009/09/29/296897.html。個人感覺XFire的方案更方便快捷,如果沒有限制的話建議使用XFire實現Web Service。
好了,感謝您看到這里。