用Delphi 6開發Web Service初探

          用Delphi?6開發Web?Service初探

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


          圖1?服務提供者、服務請求者、服務代理者的關系

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


          圖2?配置ODBC

          接著我們在Delphi6里啟動New?|?Web?Services?|?Soap?Server?Application,確定后,在接下來的對話框中選擇Web?App?Debugger?executable。我們選擇這種類型制作Web?Services是因為這個形態可以讓我們在開發時便于調試。設置其CoClass?Name為MyWebServicesTest1,如下圖所示:?


          圖3?建立Web?Services

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


          圖4?連數據源

          現在我們要定義要存儲學生信息的結構。我們New一個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.?
          因為學生信息需要傳遞到客戶端,所以它必須從?TRemotable?類派生。將這個Unit保存為DataType。??
          接著,我們要建立用戶請求服務的接口,這個接口只有一個取得成績的功能。New一個Unit,寫上如下的代碼:?
          unit?ServicesInterface;?
          interface?
          Uses?InvokeRegistry,DataType;?
          Type?
          ISoapGrade=Interface(IInvokable)?
          ['{9884ADA8-8FDC-4002-94A3-2370A269018F}']?//注意,要給這個接口分配//一個GUID,在Delphi里用Crtl+Shift+G產生。?
          Function?GetGrade(Number:Integer):TStudentInfo;StdCall;?//調用這個接口函數?
          //將返回一個TstudentInfo類型的數據。?
          End;?
          implementation?
          Initialization?
          InvRegistry.RegisterInterface(TypeInfo(ISoapGrade));?
          end.?
          將這個單元保存為ServicesInterface。?
          然后我們要編寫這個接口的實現類。在Unit2(WebModule單元)里添加實現類的定義。完整的代碼如下:?
          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;?//定義這個接口類?
          Function?TSoapGrade.GetGrade(Number:Integer):TStudentInfo;StdCall;??
          Begin?
          Result:=TStudentInfo.Create;?
          If?(?Not?Assigned(?DataModule3))?Then?
          DataModule3:=TDataModule3.Create(Nil);?//如果DataModule3沒有創建,則創建它。?
          Try??
          With?DataModule3.ADOQuery1?Do?
          Begin?
          active:=false;?
          sql[0]:='select?*?from?Grade?where?StudentID='+inttostr(Number)+';?
          active:=true;?
          //根據用戶輸入的學號和數據庫連接。?
          If?(Not?Eof)?Then?
          Begin?
          Result.Name:=FieldByName('Name').AsString;?
          Result.Grade:=FieldByName('Grade').AsFloat;??
          //從數據庫里取得合適的值給要傳遞的信息。?
          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.?
          到現在,我們已經創建了一個Web?Services!保存,編譯,運行,即在Web?App?Debugger那里完成了此Web?Services的注冊工作。那么我們這個Web?Services提供了什么功能?如何調用它?這些問題可以通過看看它的WSDL來看到。我們啟動Web?App?Debugger(在Tools菜單下),然后啟IE,在地址欄里輸入:http://localhost:1024/server.MyWebServicesTest1/wsdl/IsoapGrade,即可看到用XML語言寫成的WSDL,有了它,服務請求者就可以調用我們的服務了。 ?
          2、實現客戶端,調用服務?
          我們建立一個普通的應用程序,在form上面放置3個label、3個edit和2個button以及一個HTTPRIO1(在WebServices組件頁里),將HTTPRIO1的URL屬性設為http://localhost:1024/server.MyWebServicesTest1/soap,以便利用SOAP通信。界面如下圖所示: ?


          圖5?客戶端的傳統windows程序界面

          接著為了讓這個客戶端程序知道我們剛才建立的Web?Services的WSDL以便請求服務,我們必須在客戶端那里導入WSDL以便獲得服務的接口。幸運的是,我們根本不必很麻煩的自己編程,Delphi已經給我們做了。啟動New?|?Web?Services?|Web?Services?Importer,然后輸入WSDL所在URL地址為:http://localhost:1024/server.MyWebServicesTest1/wsdl/IsoapGrade,接著確定產生,Delphi自動會為我們產生兩個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。保存,編譯。至此我們的客戶端程序開發完畢,調用Web?Services是不是很簡單?下圖是客戶端調用的結果:?


          圖7?調用的執行結果

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

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

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

          導航

          統計

          常用鏈接

          留言簿(8)

          隨筆分類(40)

          隨筆檔案(40)

          文章分類(33)

          文章檔案(34)

          相冊

          BLOG 聯盟

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 湾仔区| 云安县| 潼关县| 滦南县| 宿州市| 华容县| 安康市| 特克斯县| 毕节市| 新龙县| 乌拉特中旗| 定西市| 拉萨市| 婺源县| 阿克苏市| 上思县| 读书| 东山县| 青铜峡市| 乌兰察布市| 株洲县| 思南县| 芒康县| 黔西| 西丰县| 定南县| 南乐县| 兴业县| 台山市| 普格县| 合阳县| 改则县| 湛江市| 灌云县| 兴隆县| 定西市| 靖安县| 晋中市| 蒲江县| 句容市| 溆浦县|