用Delphi 6開發(fā)Web Service初探

          用Delphi?6開發(fā)Web?Service初探

          簡介:“網(wǎng)絡(luò)就是計(jì)算機(jī),軟件就是服務(wù)”的思想已經(jīng)逐步深入人心。由于Web?Services能夠通過網(wǎng)絡(luò)把服務(wù)直接遞送給終端用戶,而且由眾多主流廠商所支持和描繪的美好前景也讓我們心動(dòng)不已。據(jù)有關(guān)報(bào)告預(yù)計(jì),2002年多數(shù)企業(yè)將會(huì)對(duì)于Web服務(wù)產(chǎn)生關(guān)心。另外,在2004年Fortune?2000家企業(yè)引進(jìn)的應(yīng)用軟件解決方案之中,Web服務(wù)將占很大的比重。最近,關(guān)于如何建立Web?Service的文章較多,但大多是用VS.NET完成的,而關(guān)于如何用Delphi?6開發(fā)的文章較少。本文介紹了一個(gè)用Delphi?6開發(fā)Web?Service的簡單的例子,以達(dá)到拋磚引玉之效果。?
          一、?Web?Service概述?
          盡管關(guān)于Web?Service是什么有各種各樣的理解,但下面的定義有助于讀者從不同側(cè)面、不同層次了解Web?Service。第一:Web?Service就是一個(gè)應(yīng)用程序。它通過WEB向外界提供了如何調(diào)用自身功能/服務(wù)的說明(WSDL)。這可以讓任何人從任何地方使用它所提供的這些服務(wù)。或者這樣說,Web?Service是指可以通過Web技術(shù)實(shí)現(xiàn)動(dòng)態(tài)聯(lián)動(dòng)的軟件。?
          第二:Web?Service是新興的電子商務(wù)應(yīng)用(IBM公司高級(jí)副總裁兼軟件部執(zhí)行官Steve?Mills語)。Web?Service使在Web上的彼此互聯(lián)和交互更容易、更有效,并可以大大降低目前在B2B等環(huán)境下進(jìn)行編碼定制時(shí)所需的時(shí)間。第三:Web?Services是透過網(wǎng)絡(luò)享用遠(yuǎn)程服務(wù)的一種概念。第四:Web?Services是建立可互操作的分布式應(yīng)用程序的新平臺(tái)。Web?Services的主要目標(biāo)是跨平臺(tái)的可互操作性。Web?Services平臺(tái)是一套標(biāo)準(zhǔn),它定義了應(yīng)用程序如何在WEB上實(shí)現(xiàn)互操作性。第五:Web?Services是指一套軟件工具,以及一種旨在使軟件通過互聯(lián)網(wǎng)發(fā)揮類似拼裝玩具作用的整體處理方式。第六:Web?Service是一種想把全世界的Internet/Intranet變成一個(gè)虛擬計(jì)算環(huán)境的觀念和技術(shù)。第七:Web?服務(wù)是一個(gè)被包裝成單一實(shí)體,且被發(fā)布以供其它程序使用的功能集合,或者說Web?服務(wù)是Internet上一系列能夠以編程的方式調(diào)用的相關(guān)的應(yīng)用程序功能。還有一些其它的說法,但通過這些定義,我們可以看出Web?Services的基本理念是:把軟件做成服務(wù),并且遵從相應(yīng)的標(biāo)準(zhǔn),讓不同的系統(tǒng)可以跨越平臺(tái),彼此相互兼容,具有進(jìn)行無縫通信和數(shù)據(jù)共享的能力。?
          接著,我們看看關(guān)于Web?Services的幾個(gè)核心概念。第一:Web?Services若要讓異構(gòu)平臺(tái)上不同系統(tǒng)可以相互通信和共享數(shù)據(jù),那數(shù)據(jù)在WEB上傳輸必須以一定的標(biāo)準(zhǔn)和格式進(jìn)行,這個(gè)表示數(shù)據(jù)的標(biāo)準(zhǔn)就是XML(所以微軟稱之為XML?Web?Services)。第二:不同系統(tǒng)遵從什么協(xié)議發(fā)送和接收這些標(biāo)準(zhǔn)的XML數(shù)據(jù)從而達(dá)到相互通信的目的呢?這個(gè)必須遵守的協(xié)議就是SOAP(Simple?Object?Access?Protocol簡單對(duì)象訪問協(xié)議)。SOAP是在2000年5月8日由Microsoft?和IBM等公司參與制定的規(guī)范。SOAP不與任何一種對(duì)象模式(如DCOM、CORBA等)相關(guān),它是一種獨(dú)立的、通用的、基于XML標(biāo)準(zhǔn)的、文本的對(duì)象間訪問協(xié)議。簡而言之,SOAP是運(yùn)用?XML?技術(shù)之遠(yuǎn)程過程調(diào)用?(?Remote?Procedure?Call)?的通訊協(xié)議。SOAP把對(duì)象間的訪問請(qǐng)求和響應(yīng)都打包成XML文檔,在對(duì)象間傳遞。由于SOAP傳遞的消息都以XML文檔形式發(fā)送和接收,它最理想、最自然的實(shí)現(xiàn)方式就是HTTP,所以客戶端僅需具備基本?TCP/IP?網(wǎng)絡(luò)環(huán)境,即可享用全球各處之?Web?Services。第三:其他系統(tǒng)如何知道你的Web?Services是完成什么功能的?你如何讓其他系統(tǒng)知道你的Web?Services提供了哪些服務(wù)?解決辦法就是WSDL(Web?Service?Description?Language-Web?服務(wù)描述語言)。它用機(jī)器可閱讀的格式描述了你的Web?Services,從而讓其他系統(tǒng)可以調(diào)用你所提供的服務(wù)。只要我們能夠取得特定Web?Service的WSDL,就可以從其中了解它提供的服務(wù),以及如何呼叫這個(gè)Web?Service。WSDL也是?XML?,只是有一定的規(guī)范要求。服務(wù)端提供?WSDL?文件最重要的用途就是向客戶端提供服務(wù)端接口的描述。第四:你的Web?Services如何發(fā)布以便讓世界上任何一個(gè)地點(diǎn)的人或系統(tǒng)得知你有這項(xiàng)服務(wù)從而調(diào)用它?或者作為服務(wù)請(qǐng)求者,你如何搜索你需要的Web?Services呢?這個(gè)概念為UDDI(?Universal?Description,?Discovery,?Integration-通用描述、發(fā)現(xiàn)與集成)。類似于yahoo提供的搜索網(wǎng)站的引擎和B2B電子商務(wù)的產(chǎn)品目錄搜索,Web?Service的提供者必須在UDDI注冊(cè)中心注冊(cè),而服務(wù)的請(qǐng)求者若搜索某項(xiàng)服務(wù),可到UDDI注冊(cè)中心查詢。UDDI注冊(cè)中心扮演了服務(wù)的代理者的角色。現(xiàn)在有商業(yè)的UDDI運(yùn)營商和公眾UDDI注冊(cè)中心。三者的關(guān)系如下圖所示:?


          圖1?服務(wù)提供者、服務(wù)請(qǐng)求者、服務(wù)代理者的關(guān)系

          UDDI與XML、SOAP(簡單對(duì)象訪問協(xié)議)以及WSDL(Web服務(wù)描述語言)一起成為Web?Services的事實(shí)上的核心標(biāo)準(zhǔn)。??
          二、如何用Delphi?6開發(fā)Web?Services?
          Web?Service可以由任何的技術(shù)開發(fā),Delphi6作為Microsoft?Window平臺(tái)的Web?Services?基礎(chǔ)環(huán)境與開發(fā)工具,將?RAD便利性帶入Web?Services?開發(fā)領(lǐng)域,簡化了開發(fā)Web?Services應(yīng)用程序復(fù)雜度,讓開發(fā)人員專注于應(yīng)用面的開發(fā),而無須顧及繁瑣的Web?Services規(guī)格面制作。下面我們以一個(gè)簡單的例子說明如何用Delphi?6開發(fā)Web?Services。這個(gè)例子中我們提供了查詢成績的服務(wù),客戶端(服務(wù)請(qǐng)求者——可以是瀏覽器、Windows程序甚或Linux程序,在這里,為了簡單起見,我們用了傳統(tǒng)的Windows程序)可以輸入學(xué)號(hào),查詢出相應(yīng)的成績來。?
          1、創(chuàng)建服務(wù)?
          首先我們要建立一個(gè)成績表,名稱為Grade。我們?cè)赟QL?SERVER里面建立一個(gè)TEST庫,在其下建立Grade表,它有三個(gè)字段,分別為StudentID、Name、Grade。隨后我們隨便向里面添加一些數(shù)據(jù)。然后我們配置一下ODBC,在系統(tǒng)DSN中添加一個(gè)數(shù)據(jù)源,名稱起為Grade,指向我們剛才建立的TEST庫。如圖二所示:?


          圖2?配置ODBC

          接著我們?cè)贒elphi6里啟動(dòng)New?|?Web?Services?|?Soap?Server?Application,確定后,在接下來的對(duì)話框中選擇Web?App?Debugger?executable。我們選擇這種類型制作Web?Services是因?yàn)檫@個(gè)形態(tài)可以讓我們?cè)陂_發(fā)時(shí)便于調(diào)試。設(shè)置其CoClass?Name為MyWebServicesTest1,如下圖所示:?


          圖3?建立Web?Services

          這時(shí)Delphi會(huì)自動(dòng)給我們生成一個(gè)Form和一個(gè)WebModule,WebModule中的幾個(gè)組件是幫助我們用SOAP進(jìn)行通信和發(fā)布WSDL的,有了它們,我們就可以開始集中精力編寫實(shí)際的應(yīng)用代碼了。現(xiàn)在我們New一個(gè)Data?Module?,在File菜單里選擇New|Data?Module,在其上放置一個(gè)ADOQuery以連接我們的數(shù)據(jù),設(shè)置其ConnectionString屬性為Provider=MSDASQL.1;Password=sa;Persist?Security?Info=True;User?ID=sa;Data?Source=Grade(選擇Build,然后選擇微軟提供的ODBC驅(qū)動(dòng),選下一步,使用指定的數(shù)據(jù)源名稱Grade,輸入用戶名稱和密碼確定即可)。將該單元保存為dm。如圖所示:?


          圖4?連數(shù)據(jù)源

          現(xiàn)在我們要定義要存儲(chǔ)學(xué)生信息的結(jié)構(gòu)。我們New一個(gè)Unit,在file菜單里選擇New|Unit,寫上如下的代碼:?
          unit?DataType;?
          interface?
          Uses?InvokeRegistry;?
          Type?
          TStudentInfo=Class(TRemotable)?
          Private?
          FName?:?String;?
          FGrade?:?Single;?
          published?
          Property?Name?:?String?Read?FName?Write?FName;?
          Property?Grade?:?Single?Read?FGrade?Write?FGrade;?
          end;?
          implementation?
          Initialization?
          RemClassRegistry.RegisterXSClass(TStudentInfo);?
          Finalization?
          RemClassRegistry.UnRegisterXSClass(TStudentInfo);?
          end.?
          因?yàn)閷W(xué)生信息需要傳遞到客戶端,所以它必須從?TRemotable?類派生。將這個(gè)Unit保存為DataType。??
          接著,我們要建立用戶請(qǐng)求服務(wù)的接口,這個(gè)接口只有一個(gè)取得成績的功能。New一個(gè)Unit,寫上如下的代碼:?
          unit?ServicesInterface;?
          interface?
          Uses?InvokeRegistry,DataType;?
          Type?
          ISoapGrade=Interface(IInvokable)?
          ['{9884ADA8-8FDC-4002-94A3-2370A269018F}']?//注意,要給這個(gè)接口分配//一個(gè)GUID,在Delphi里用Crtl+Shift+G產(chǎn)生。?
          Function?GetGrade(Number:Integer):TStudentInfo;StdCall;?//調(diào)用這個(gè)接口函數(shù)?
          //將返回一個(gè)TstudentInfo類型的數(shù)據(jù)。?
          End;?
          implementation?
          Initialization?
          InvRegistry.RegisterInterface(TypeInfo(ISoapGrade));?
          end.?
          將這個(gè)單元保存為ServicesInterface。?
          然后我們要編寫這個(gè)接口的實(shí)現(xiàn)類。在Unit2(WebModule單元)里添加實(shí)現(xiàn)類的定義。完整的代碼如下:?
          unit?Unit2;?
          interface?
          uses?SysUtils,?Classes,?HTTPApp,?WSDLPub,?SOAPPasInv,?SOAPHTTPPasInv,?SoapHTTPDisp,?WebBrokerSOAP;?
          type?
          TWebModule2?=?class(TWebModule)?
          HTTPSoapDispatcher1:?THTTPSoapDispatcher;?
          HTTPSoapPascalInvoker1:?THTTPSoapPascalInvoker;?
          WSDLHTMLPublish1:?TWSDLHTMLPublish;?
          private?
          {?Private?declarations?}?
          public?
          {?Public?declarations?}?
          end;?
          var?
          WebModule2:?TWebModule2;?
          implementation?
          uses?WebReq,InvokeRegistry,DataType,ServicesInterface,dm;??
          Type?
          TSoapGrade=class(TInvokableClass,ISoapGrade)?
          Protected?
          Function?GetGrade(Number:Integer):TStudentInfo;StdCall;?
          End;?//定義這個(gè)接口類?
          Function?TSoapGrade.GetGrade(Number:Integer):TStudentInfo;StdCall;??
          Begin?
          Result:=TStudentInfo.Create;?
          If?(?Not?Assigned(?DataModule3))?Then?
          DataModule3:=TDataModule3.Create(Nil);?//如果DataModule3沒有創(chuàng)建,則創(chuàng)建它。?
          Try??
          With?DataModule3.ADOQuery1?Do?
          Begin?
          active:=false;?
          sql[0]:='select?*?from?Grade?where?StudentID='+inttostr(Number)+';?
          active:=true;?
          //根據(jù)用戶輸入的學(xué)號(hào)和數(shù)據(jù)庫連接。?
          If?(Not?Eof)?Then?
          Begin?
          Result.Name:=FieldByName('Name').AsString;?
          Result.Grade:=FieldByName('Grade').AsFloat;??
          //從數(shù)據(jù)庫里取得合適的值給要傳遞的信息。?
          End?
          Else?
          Begin?
          Result.Name:='未查詢到!';?Result.Grade:=0;?
          End;?
          Close;?
          End;?
          Finally?
          DataModule3.Free;?DataModule3:=Nil;?
          End;?
          End;?
          initialization?
          WebRequestHandler.WebModuleClass:=TWebModule2;?
          InvRegistry.RegisterInvokableClass(TSoapGrade);?
          end.?
          到現(xiàn)在,我們已經(jīng)創(chuàng)建了一個(gè)Web?Services!保存,編譯,運(yùn)行,即在Web?App?Debugger那里完成了此Web?Services的注冊(cè)工作。那么我們這個(gè)Web?Services提供了什么功能?如何調(diào)用它?這些問題可以通過看看它的WSDL來看到。我們啟動(dòng)Web?App?Debugger(在Tools菜單下),然后啟IE,在地址欄里輸入:http://localhost:1024/server.MyWebServicesTest1/wsdl/IsoapGrade,即可看到用XML語言寫成的WSDL,有了它,服務(wù)請(qǐng)求者就可以調(diào)用我們的服務(wù)了。 ?
          2、實(shí)現(xiàn)客戶端,調(diào)用服務(wù)?
          我們建立一個(gè)普通的應(yīng)用程序,在form上面放置3個(gè)label、3個(gè)edit和2個(gè)button以及一個(gè)HTTPRIO1(在WebServices組件頁里),將HTTPRIO1的URL屬性設(shè)為http://localhost:1024/server.MyWebServicesTest1/soap,以便利用SOAP通信。界面如下圖所示: ?


          圖5?客戶端的傳統(tǒng)windows程序界面

          接著為了讓這個(gè)客戶端程序知道我們剛才建立的Web?Services的WSDL以便請(qǐng)求服務(wù),我們必須在客戶端那里導(dǎo)入WSDL以便獲得服務(wù)的接口。幸運(yùn)的是,我們根本不必很麻煩的自己編程,Delphi已經(jīng)給我們做了。啟動(dòng)New?|?Web?Services?|Web?Services?Importer,然后輸入WSDL所在URL地址為:http://localhost:1024/server.MyWebServicesTest1/wsdl/IsoapGrade,接著確定產(chǎn)生,Delphi自動(dòng)會(huì)為我們產(chǎn)生兩個(gè)unit,這樣接口的事情就全部交給Delphi,我們就不必管了。如圖所示: ?


          圖6?引入WSDL

          最后,在Form1的確定按鈕的OnClick事件里添加如下的代碼:?
          procedure?TForm1.Button1Click(Sender:?TObject);?
          Var?
          Student:TStudentInfo;?
          begin?
          Student:=(HTTPRIO1?As?ISoapGrade).GetGrade(StrToInt(Edit1.Text));?
          If?(Assigned(Student))?Then?
          Begin?
          Edit2.Text:=Student.Name;?
          Edit3.Text:=floattostr(Student.Grade);?
          End;?
          end;?
          并注意要在unit1的uses中添加unit2和unit3。保存,編譯。至此我們的客戶端程序開發(fā)完畢,調(diào)用Web?Services是不是很簡單?下圖是客戶端調(diào)用的結(jié)果:?


          圖7?調(diào)用的執(zhí)行結(jié)果

          目前互聯(lián)網(wǎng)上已經(jīng)有一些網(wǎng)站羅列了許多Web?Services,例如http://www.xmethods.com,上面有關(guān)于各個(gè)Web ?Services說明以及WSDL的描述,讀者若有興趣可以自己編寫客戶端程序引入上面的WSDL。當(dāng)讀者能夠利用自己編寫的客戶端跨越各種平臺(tái)和網(wǎng)絡(luò)結(jié)構(gòu),調(diào)用地球另一側(cè)的人也許用java寫成的Web?Services時(shí),相信你一定為Web?Services的強(qiáng)大而歡欣鼓舞。?
          三、小結(jié)?
          從上面的例子我們可以看到,只要理解了Web?Services的概念,熟悉了Web?Services的開發(fā)步驟,在Delphi的幫助下,開發(fā)Web?Services將不是一件很困難的事情。Web?Services最適合用于開發(fā)跨平臺(tái)和跨網(wǎng)絡(luò)進(jìn)行通信(因?yàn)槭褂胔ttp協(xié)議為防火墻所允許)的程序,可以跨越異質(zhì)架構(gòu),聯(lián)系客戶、供應(yīng)商、企業(yè)伙伴以及企業(yè)內(nèi)部之信息系統(tǒng),是電子商務(wù)B2B集成的最佳選擇。各個(gè)公司只要把商務(wù)邏輯“暴露”出來,成為Web?Service,就可以讓任何指定的合作伙伴調(diào)用這些商務(wù)邏輯,而不管他們的系統(tǒng)在什么平臺(tái)上運(yùn)行,使用什么開發(fā)語言。但也沒有必要把所有的軟件都做成Web?Services,正如“尺有所短,寸有所長”一樣,傳統(tǒng)的windows程序也大有用武之地。Web?Services是目前很熱門也是正在迅速發(fā)展著的一項(xiàng)技術(shù),本文只是作者在學(xué)習(xí)中的一點(diǎn)小體會(huì),肯定有理解不深刻甚或錯(cuò)誤的地方,歡迎大家予以指正。?

          posted on 2006-06-01 16:45 【Xine】中文站 閱讀(1669) 評(píng)論(0)  編輯  收藏 所屬分類: Delphi Kylix

          <2025年5月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(8)

          隨筆分類(40)

          隨筆檔案(40)

          文章分類(33)

          文章檔案(34)

          相冊(cè)

          BLOG 聯(lián)盟

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 区。| 米易县| 宜都市| 公安县| 明光市| 罗城| 镶黄旗| 荣昌县| 文山县| 上林县| 那坡县| 天等县| 麻城市| 浦东新区| 广灵县| 甘肃省| 惠东县| 本溪| 青阳县| 乐都县| 江源县| 普安县| 辽阳县| 青岛市| 平塘县| 洪洞县| 岳阳市| 新津县| 乌苏市| 平山县| 青阳县| 福州市| 炎陵县| 福贡县| 乌苏市| 宽城| 榆林市| 双柏县| 开江县| 濮阳县| 鄂伦春自治旗|