一、WebService簡介
1.1 WebService是什么
Web Service就是為了使原來各孤立的站點(diǎn)之間的信息能夠相互通信、共享而提出的一種接口。
通過使用WebService,您的應(yīng)用程序可以向全世界發(fā)布信息,或提供某項(xiàng)功能,它是基于Web的服務(wù),通過Web進(jìn)行發(fā)布、查找和使用。
WebService腳本平臺需支持XML+HTTP。
HTTP協(xié)議是最常用的因特網(wǎng)協(xié)議。
XML提供了一種可用于不同的平臺和編程語言之間的語言。
1.2 WebService的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
(1)跨平臺調(diào)用(WebService不局限于操作系統(tǒng),你可以在Windows上調(diào)用linux上的WebService服務(wù),反之亦然,其他系統(tǒng)同理);
(2)跨語言調(diào)用(WebService不局限于編程語言,你可以在Java語言中調(diào)用C#語言提供的WebService服務(wù),反之亦然,其他語言同理);
(3)可遠(yuǎn)程調(diào)用(通過使用WebService,您的應(yīng)用程序可以向全世界發(fā)布信息,或提供某項(xiàng)功能,只要有Internet)。
缺點(diǎn):
(1)WebService使用了XML對數(shù)據(jù)封裝,會造成大量的數(shù)據(jù)要在網(wǎng)絡(luò)中傳輸。
(2)WebService規(guī)范沒有規(guī)定任何與實(shí)現(xiàn)相關(guān)的細(xì)節(jié),包括對象模型、編程語言,這一點(diǎn),它不如CORBA。
1.3 WebService適用場合
1、跨防火墻通信
如果應(yīng)用程序有成千上萬的用戶,而且分布在世界各地,那么客戶端和服務(wù)器之間的通信將是一個棘手的問題。因?yàn)榭蛻舳撕头?wù)器之間通常會有防火墻或者代理服務(wù)器。在這種情況下,使用DCOM就不是那么簡單,通常也不便于把客戶端程序發(fā)布到數(shù)量如此龐大的每一個用戶手中。傳統(tǒng)的做法是,選擇用瀏覽器作為客戶 端,寫下一大堆ASP頁面,把應(yīng)用程序的中間層暴露給最終用戶。這樣做的結(jié)果是開發(fā)難度大,程序很難維護(hù)。如果中間層組件換成WebService的話, 就可以從用戶界面直接調(diào)用中間層組件。從大多數(shù)人的經(jīng)驗(yàn)來看,在一個用戶界面和中間層有較多交互的應(yīng)用程序中,使用WebService這種結(jié)構(gòu),可以節(jié) 省花在用戶界面編程上20%的開發(fā)時間。
2、應(yīng)用程序集成
企業(yè)級的應(yīng)用程序開發(fā)者都知道,企業(yè)里經(jīng)常都要把用不同語言寫成的、在不同平臺上運(yùn)行的各種程序集成起來,而這種集成將花費(fèi)很大的開發(fā)力量。應(yīng)用程序經(jīng)常需要從運(yùn)行在IBM主機(jī)上的程序中獲取數(shù)據(jù);或者把數(shù)據(jù)發(fā)送到主機(jī)或UNIX應(yīng)用程序中去。即使在同一個平臺上,不同軟件廠商生產(chǎn)的各種軟件也常常需要集 成起來。通過WebService,可以很容易的集成不同結(jié)構(gòu)的應(yīng)用程序。
3、B2B集成
用WebService集成應(yīng)用程序,可以使公司內(nèi)部的商務(wù)處理更加自動化。但當(dāng)交易跨越供應(yīng)商和客戶、突破公司的界限時會怎么樣呢?跨公司的商務(wù)交易集成通常叫做B2B集成。WebService是B2B集成成功的關(guān)鍵。通過WebService,公司可以把關(guān)鍵的商務(wù)應(yīng)用“暴露”給指定的供應(yīng)商和客戶。例如,把電子下單系統(tǒng)和電子發(fā)票系統(tǒng)“暴露”出來,客戶就可以以電子的方式發(fā)送訂單,供應(yīng)商則可以以電子的方式發(fā)送原料采購發(fā)票。當(dāng)然,這并不是一個 新的概念,EDI(電子文檔交換)早就是這樣了。但是,WebService的實(shí)現(xiàn)要比EDI簡單得多,而且WebService運(yùn)行在Internet 上,在世界任何地方都可輕易實(shí)現(xiàn),其運(yùn)行成本就相對較低。不過,WebService并不像EDI那樣,是文檔交換或B2B集成的完整解決方案。 WebService只是B2B集成的一個關(guān)鍵部分,還需要許多其它的部分才能實(shí)現(xiàn)集成。
用WebService來實(shí)現(xiàn)B2B集成的最大好處在于可以輕易實(shí)現(xiàn)互操作性。只要把商務(wù)邏輯“暴露”出來,成為WebService,就可以讓任何指定 的合作伙伴調(diào)用這些商務(wù)邏輯,而不管他們的系統(tǒng)在什么平臺上運(yùn)行,使用什么開發(fā)語言。這樣就大大減少了花在B2B集成上的時間和成本,讓許多原本無法承受 EDI的中小企業(yè)也能實(shí)現(xiàn)B2B集成。
4、軟件和數(shù)據(jù)重用
軟件重用是一個很大的主題,重用的形式很多,重用的程度有大有小。最基本的形式是源代碼模塊或者類一級的重用,一種形式是二進(jìn)制形式的組件重用。采用 WebService應(yīng)用程序可以用標(biāo)準(zhǔn)的方法把功能和數(shù)據(jù)“暴露”出來,供其它應(yīng)用程序使用,達(dá)到業(yè)務(wù)級重用。
1.4 WebService不適用場合
1、單機(jī)應(yīng)用程序
目前,企業(yè)和個人還使用著很多桌面應(yīng)用程序。其中一些只需要與本機(jī)上的其它程序通信。在這種情況下,最好就不要用WebService,只要用本地的 API就可以了。COM非常適合于在這種情況下工作,因?yàn)樗刃∮挚?。運(yùn)行在同一臺服務(wù)器上的服務(wù)器軟件也是這樣。最好直接用COM或其它本地的API來 進(jìn)行應(yīng)用程序間的調(diào)用。當(dāng)然WebService也能用在這些場合,但那樣不僅消耗太大,而且不會帶來任何好處。
2、局域網(wǎng)的同構(gòu)應(yīng)用程序
在許多應(yīng)用中,所有的程序都是用VB或VC開發(fā)的,都在Windows平臺下使用COM,都運(yùn)行在同一個局域網(wǎng)上。例如,有兩個服務(wù)器應(yīng)用程序需要相互通 信,或者有一個Win32或WinForm的客戶程序要連接局域網(wǎng)上另一個服務(wù)器的程序。在這些程序里,使用DCOM會比SOAP/HTTP有效得多。與 此相類似,如果一個.NET程序要連接到局域網(wǎng)上的另一個.NET程序,應(yīng)該使用.NETremoting。有趣的是,在.NETremoting 中,也可以指定使用SOAP/HTTP來進(jìn)行WebService調(diào)用。不過最好還是直接通過TCP進(jìn)行RPC調(diào)用,那樣會有效得多。
1.5 WebService和Socket的對比
(1)Socket是基于TCP/IP的傳輸層協(xié)議。
Webservice是基于HTTP協(xié)議傳輸數(shù)據(jù),http是基于tcp的應(yīng)用層協(xié)議。
Webservice采用了基于http的soap協(xié)議傳輸數(shù)據(jù)。
(2)Socket接口通過流傳輸,不支持面向?qū)ο蟆?/p>
Webservice接口支持面向?qū)ο?,最終webservice將對象進(jìn)行序列化后通過流傳輸。
Webservice采用soap協(xié)議進(jìn)行通信,不需專門針對數(shù)據(jù)流的發(fā)送和接收進(jìn)行處理,是一種跨平臺的面向?qū)ο筮h(yuǎn)程調(diào)用技術(shù)。
(3)Socket適用于高性能大數(shù)據(jù)的傳輸,傳輸?shù)臄?shù)據(jù)需要手動處理,socket通信的接口協(xié)議需要自定義。
二、重要名詞
2.1、JSWDL、AXP、JAXM的解
Web ServiceWeb Service是基于網(wǎng)絡(luò)的、分布式的模塊化組件,它執(zhí)行特定的任務(wù),遵守具體的技術(shù)規(guī)范,這些規(guī)范使得Web Service能與其他兼容的組件進(jìn)行互操作。
JAXP(Java API for XML Parsing)定義了在Java中使用DOM, SAX, XSLT的通用的接口。這樣在你的程序中你只要使用這些通用的接口,當(dāng)你需要改變具體的實(shí)現(xiàn)時候也不需要修改代碼。
JAXM(Java API for XML Messaging)是為SOAP通信提供訪問方法和傳輸機(jī)制的API。 ?
UDDI的目的是為電子商務(wù)建立標(biāo)準(zhǔn);UDDI是一套基于Web的、分布式的、為Web Service提供的、信息注冊中心的實(shí)現(xiàn)標(biāo)準(zhǔn)規(guī)范,同時也包含一組使企業(yè)能將自身提供的Web Service注冊,以使別的企業(yè)能夠發(fā)現(xiàn)的訪問協(xié)議的實(shí)現(xiàn)標(biāo)準(zhǔn)。
2.2、CORBA是什么?用途是什么?
CORBA標(biāo)準(zhǔn)是公共對象請求代理結(jié)構(gòu)(Common Object Request Broker Architecture),由對象管理組織 (Object Management Group,縮寫為 OMG)標(biāo)準(zhǔn)化。它的組成是接口定義語言(IDL), 語言綁定(binding:也譯為聯(lián)編)和允許應(yīng)用程序間互操作的協(xié)議。 其目的為:用不同的程序設(shè)計語言書寫在不同的進(jìn)程中運(yùn)行,為不同的操作系統(tǒng)開發(fā)。
2.3、XML+XSD
WebService采用HTTP協(xié)議傳輸數(shù)據(jù),采用XML格式封裝數(shù)據(jù)(即XML中說明調(diào)用遠(yuǎn)程服務(wù)對象的哪個方法,傳遞的參數(shù)是什么,以及服務(wù)對象的 返回結(jié)果是什么)。XML是WebService平臺中表示數(shù)據(jù)的格式。除了易于建立和易于分析外,XML主要的優(yōu)點(diǎn)在于它既是平臺無關(guān)的,又是廠商無關(guān) 的。無關(guān)性是比技術(shù)優(yōu)越性更重要的:軟件廠商是不會選擇一個由競爭對手所發(fā)明的技術(shù)的。?
XML解決了數(shù)據(jù)表示的問題,但它沒有定義一套標(biāo)準(zhǔn)的數(shù)據(jù)類型,更沒有說怎么去擴(kuò)展這套數(shù)據(jù)類型。例如,整形數(shù)到底代表什么?16位,32位,64位?這 些細(xì)節(jié)對實(shí)現(xiàn)互操作性很重要。XML Schema(XSD)就是專門解決這個問題的一套標(biāo)準(zhǔn)。它定義了一套標(biāo)準(zhǔn)的數(shù)據(jù)類型,并給出了一種語言來擴(kuò)展這套數(shù)據(jù)類型。WebService平臺就 是用XSD來作為其數(shù)據(jù)類型系統(tǒng)的。當(dāng)你用某種語言(如VB.NET或C#)來構(gòu)造一個Web?service時,為了符合WebService標(biāo)準(zhǔn),所 有你使用的數(shù)據(jù)類型都必須被轉(zhuǎn)換為XSD類型。你用的工具可能已經(jīng)自動幫你完成了這個轉(zhuǎn)換,但你很可能會根據(jù)你的需要修改一下轉(zhuǎn)換過程。
2.4、SOAP
???WebService通過HTTP協(xié)議發(fā)送請求和接收結(jié)果時,發(fā)送的請求內(nèi)容和結(jié)果內(nèi)容都采用XML格式封裝,并增加了一些特定的HTTP消息頭,以說明 HTTP消息的內(nèi)容格式,這些特定的HTTP消息頭和XML內(nèi)容格式就是SOAP協(xié)議。SOAP提供了標(biāo)準(zhǔn)的RPC方法來調(diào)用Web Service。
??SOAP協(xié)議 = HTTP協(xié)議 + XML數(shù)據(jù)格式
?SOAP協(xié)議定義了SOAP消息的格式,SOAP協(xié)議是基于HTTP協(xié)議的,SOAP也是基于XML和XSD的,XML是SOAP的數(shù)據(jù)編碼方式。打個比 喻:HTTP就是普通公路,XML就是中間的綠色隔離帶和兩邊的防護(hù)欄,SOAP就是普通公路經(jīng)過加隔離帶和防護(hù)欄改造過的高速公路。
2.5、WSDL
好比我們?nèi)ド痰曩I東西,首先要知道商店里有什么東西可買,然后再來購買,商家的做法就是張貼廣告海報。WebService也一樣,WebService客戶端要調(diào)用一個WebService服務(wù),首先要有知道這個服務(wù)的地址在哪,以及這個服務(wù)里有什么方 法可以調(diào)用,所以,WebService務(wù)器端首先要通過一個WSDL文件來說明自己家里有啥服務(wù)可以對外調(diào)用,服務(wù)是什么(服務(wù)中有哪些方法,方法接受 的參數(shù)是什么,返回值是什么),服務(wù)的網(wǎng)絡(luò)地址用哪個url地址表示,服務(wù)通過什么方式來調(diào)用。
WSDL(Web Services Description Language)就是這樣一個基于XML的語言,用于描述Web?Service及其函數(shù)、參數(shù)和返回值。它是WebService客戶端和服務(wù)器端都 能理解的標(biāo)準(zhǔn)格式。因?yàn)槭腔赬ML的,所以WSDL既是機(jī)器可閱讀的,又是人可閱讀的,這將是一個很大的好處。一些最新的開發(fā)工具既能根據(jù)你的 Web?service生成WSDL文檔,又能導(dǎo)入WSDL文檔,生成調(diào)用相應(yīng)WebService的代理類代碼。
WSDL文件保存在Web服務(wù)器上,通過一個url地址就可以訪問到它??蛻舳艘{(diào)用一個WebService服務(wù)之前,要知道該服務(wù)的WSDL文件的地址。 WebService服務(wù)提供商可以通過兩種方式來暴露它的WSDL文件地址:1.注冊到UDDI服務(wù)器,以便被人查找;2.直接告訴給客戶端調(diào)用者。
四、WebService開發(fā)
WebService開發(fā)可以分為服務(wù)器端開發(fā)和客戶端開發(fā)兩個方面
4.1、服務(wù)端開發(fā)
把公司內(nèi)部系統(tǒng)的業(yè)務(wù)方法發(fā)布成WebService服務(wù),供遠(yuǎn)程合作單位和個人調(diào)用。(借助一些WebService框架可以很輕松地把自己的業(yè)務(wù)對象發(fā)布成WebService服務(wù),Java方面的典型WebService框架包括:axis,xfire,cxf 等,java ee服務(wù)器通常也支持發(fā)布WebService服務(wù),例如JBoss。)
4.2、客戶端開發(fā)?
調(diào)用別人發(fā)布的WebService服務(wù),大多數(shù)人從事的開發(fā)都屬于這個方面,例如,調(diào)用天氣預(yù)報WebService服務(wù)。(使用廠 商的WSDL2Java之類的工具生成靜態(tài)調(diào)用的代理類代碼;使用廠商提供的客戶端編程API類;使用SUN公司早期標(biāo)準(zhǔn)的jax-rpc開發(fā)包;使用 SUN公司最新標(biāo)準(zhǔn)的jax-ws開發(fā)包。當(dāng)然SUN已被ORACLE收購)
4.3、WebService 的工作調(diào)用原理
? 對客戶端而言,我們給這各類WebService客戶端API傳遞wsdl文件的url地址,這些API就會創(chuàng)建出底層的代理類,我調(diào)用 這些代理,就可以訪問到webservice服務(wù)。代理類把客戶端的方法調(diào)用變成soap格式的請求數(shù)據(jù)再通過HTTP協(xié)議發(fā)出去,并把接收到的soap 數(shù)據(jù)變成返回值返回。對服務(wù)端而言,各類WebService框架的本質(zhì)就是一個大大的Servlet,當(dāng)遠(yuǎn)程調(diào)用客戶端給它通過http協(xié)議發(fā)送過來 soap格式的請求數(shù)據(jù)時,它分析這個數(shù)據(jù),就知道要調(diào)用哪個java類的哪個方法,于是去查找或創(chuàng)建這個對象,并調(diào)用其方法,再把方法返回的結(jié)果包裝成 soap格式的數(shù)據(jù),通過http響應(yīng)消息回給客戶端。
七、java調(diào)用webservice接口的幾種方法
7.1 直接AXIS調(diào)用遠(yuǎn)程的webService
我覺得這種方法比較適合那些高手,他們能直接看懂XML格式的WSDL文件,我自己是看不懂的,尤其我不是專門搞這行的,即使一段時間看懂,后來也就忘記了。直接調(diào)用模式如下:
import java.util.Date;import java.text.DateFormat;import org.apache.axis.client.Call;import org.apache.axis.client.Service;import javax.xml.namespace.QName;import java.lang.Integer;import javax.xml.rpc.ParameterMode;public class caClient {????public static void main(String[] args) {????????try {????????????String endpoint = "http://localhost:8080/ca3/services/caSynrochnized?wsdl";?? ? ? ? ? ?//直接引用遠(yuǎn)程的wsdl文件?? ? ? ? ? ?//以下都是套路 ?? ? ? ? ? ?Service service = new Service();?? ? ? ? ? ?Call call = (Call) service.createCall();?? ? ? ? ? ?call.setTargetEndpointAddress(endpoint);?? ? ? ? ? ?call.setOperationName("addUser");//WSDL里面描述的接口名稱?? ? ? ? ? ?call.addParameter("userName", org.apache.axis.encoding.XMLType.XSD_DATE,?? ? ? ? ? ? ? ? ? ?javax.xml.rpc.ParameterMode.IN);//接口的參數(shù)?? ? ? ? ? ?call.setReturnType(org.apache.axis.encoding.XMLType.XSD_STRING);//設(shè)置返回類型 ?? ? ? ? ? ?String temp = "測試人員";?? ? ? ? ? ?String result = (String) call.invoke(new Object[]{temp});//給方法傳遞參數(shù),并且調(diào)用方法?? ? ? ? ? ?System.out.println("result is " + result);?? ? ? ?} catch (Exception e) {????????????System.err.println(e.toString());?? ? ? ?}????}}
7.2 直接SOAP調(diào)用遠(yuǎn)程的webservice
這種模式我從來沒有見過,也沒有試過,但是網(wǎng)絡(luò)上有人貼出來,我也轉(zhuǎn)過來
import org.apache.soap.util.xml.*;import org.apache.soap.*;import org.apache.soap.rpc.*;import java.io.*;import java.net.*;import java.util.Vector;public class caService {????public static String getService(String user) {????????URL url = null;?? ? ? ?try {????????????url = new URL("http://192.168.0.100:8080/ca3/services/caSynrochnized");?? ? ? ?} catch (MalformedURLException mue) {????????????return mue.getMessage();?? ? ? ?}????????????????// This is the main SOAP object?? ? ? ?Call soapCall = new Call();?? ? ? ??? ? ? ?// Use SOAP encoding?? ? ? ?soapCall.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);?? ? ? ??? ? ? ?// This is the remote object we're asking for the price?? ? ? ?soapCall.setTargetObjectURI("urn:xmethods-caSynrochnized");?? ? ? ??? ? ? ?// This is the name of the method on the above object?? ? ? ?soapCall.setMethodName("getUser");?? ? ? ??? ? ? ?// We need to send the ISBN number as an input parameter to the method?? ? ? ?Vector soapParams = new Vector();?? ? ? ??? ? ? ?// name, type, value, encoding style?? ? ? ?Parameter isbnParam = new Parameter("userName", String.class, user, null);?? ? ? ?soapParams.addElement(isbnParam);?? ? ? ?soapCall.setParams(soapParams);?? ? ? ?try {????????????// Invoke the remote method on the object?? ? ? ? ? ?Response soapResponse = soapCall.invoke(url, "");?? ? ? ? ? ??? ? ? ? ? ?// Check to see if there is an error, return "N/A"?? ? ? ? ? ?if (soapResponse.generatedFault()) {????????????????Fault fault = soapResponse.getFault();?? ? ? ? ? ? ? ?String f = fault.getFaultString();?? ? ? ? ? ? ? ?return f;?? ? ? ? ? ?} else {????????????????// read result?? ? ? ? ? ? ? ?Parameter soapResult = soapResponse.getReturnValue();?? ? ? ? ? ? ? ??? ? ? ? ? ? ? ?// get a string from the result?? ? ? ? ? ? ? ?return soapResult.getValue().toString();?? ? ? ? ? ?}????????} catch (SOAPException se) {????????????return se.getMessage();?? ? ? ?}????}}
7.3 使用wsdl2java把WSDL文件轉(zhuǎn)成本地類,然后像本地類一樣
這是像我這種懶人最喜歡的方式,仍然以前面的global weather report為例。
首先java org.apache.axis.wsdl.WSDL2Java
http://www.webservicex.net/globalweather.asmx.WSDL
原本的網(wǎng)址是http://www.webservicex.net/globalweather.asmx?WSDL,中間個各問號,但是Linux下面它不能解析,所以去掉問號,改為點(diǎn)號。
那么就會出現(xiàn)4個文件:
GlobalWeather.java?
GlobalWeatherLocator.java?
GlobalWeatherSoap.java?
GlobalWeatherSoapStub.java
其中GlobalWeatherSoap.java是我們最為關(guān)心的接口文件,如果你對RMI等SOAP實(shí)現(xiàn)的具體細(xì)節(jié)不感興趣,那么你只需要看接口文件即可,在使用的時候,引入這個接口即可,就好像使用本地類一樣。