1. 程式人生 > >用Delphi編寫WebService的心得體會

用Delphi編寫WebService的心得體會

相關名詞:

     Dispatch: 派遣,分派 Invoke: 呼叫 Invokable: 可呼叫介面

    TReomtable: WebService中自定義類都是繼承自該類 TSOAPAttachment: Attachment:附件,一種流型別,可以返回流資料 CGI:(EXE)

     ISAPI:(DLL) Base64編碼: uses EncdDecd; s := EncodeString(s); //加 base64 編碼 s := DecodeString( str ); //解碼 UTF8: UTF8 是8位的UNICODE字元,而ASCII是7位 ,gb2312和unicode是2位元組/字,utf8是3位元組/字utf8類似以前的8位轉7位的編碼,是為 了 在網路間不同系統的通訊方便而作的轉換。 幾乎所有用.Net寫的WebService只支援DOC方式、Delphi寫的只支援RPC方式;J2ME目前對Web Service的支援僅限於RFC172,而 RFC172要求必須為DOC方式(sun怎麼偏袒MS?)!

     為了在設計中減少障礙,下面還介紹幾個概念。

    1) SOAP:SOAP是一種簡單有效的資料傳輸協議,用於分散式網路環境下資料資訊交換,它以XML 作為資料傳輸的格式,搭配Internet上標準的傳輸協議HTTP、SMTP、TCP等來傳送資訊。從本質上看,SOAP事實上只是將Request和Response經由XML格式把資料打包,達到雙方溝通的目的。

     2) WSDL:WSDL(Web Service Description Language)是一種以XML格式描述的Web Service語言,當Web Service Provider 要對外公佈提供的 Web Service,就需要通過WSDL來構建描述語言。 在WSDL中有兩個非常重要的要素: :此WSDL檔案所要描述的Web Service集合; 每一個Port代表外界Client可以和此Service溝通的一個進入點,一個Port會指定一個Binding方式。

     3):處理中文亂碼的問題: 將HttpRio的 Converter 的 Options 的 soUTF8InHeader 設為 True 將生成soap訊息的HTTPSoapDispatcher控制元件,新增encoding為gb2312 HTTPRIO.HTTPWebNode.UseUTF8InHeader := True;

    4)在Delphi中,能夠傳遞的自定義型別的物件要繼承TRemotable,

    5:修正一個伺服器端的一個Bug:將ISAPIThreadPool和ISAPIApp的次序變一下:ISAPIApp必須在ISAPIThreadPool之前: uses ... ISAPIApp, ISAPIThreadPool 解決如下錯誤: Received content of invalid Content-Type setting:text/html -SOAP"expects"text/xml" 6:"XML document must have a top level element. Line: 0" 錯誤,我該如何解決?? 哈納斯 (2002-08-05 17:26:00) 我也曾碰到同樣的問題 解決方法是:別設httprio的wsdllocation,設它的url 如http://localhost/mydir/project1.exe/wsdl/IFIRST mydir是你的可執行的虛擬目錄,IFIRST是你定義的介面名 ***********************************************************************************************

  Delphi中WebService包含的元件解釋(有7個)     (1) THTTPRIO-------:使用Http訊息來呼叫遠端使用SOAP的介面物件

    (2) THTTPReqResp---:給伺服器傳送一個SOAP訊息, THTTPReqResp在可呼叫介面上執行一個方法請求.   

    (3) TOPToSoapDomConvert ----:TOPToSoapDomConvert處理Soap方法請求的組合與分發

    (4) TSoapConnection:TSoapConnection在客戶端的多層資料庫應用中建立並維護客戶端和作為WebService 的遠端應用伺服器間的連線

    (5) THTTPSoapDispatcher -----:通過將Soap訊息轉發給呼叫者,THTTPSoapDispatcher對Soap訊息做出響應.

    (6) TWSDLHTMLPublish -----:TWSDLHTMLPublish釋出描敘webService應用的Wsdl文件

     (7) THTTPSoapPascalInvoker -----:THTTPSoapPascalInvoker解釋Soap的請求資訊,並執行相應的可呼叫介面. ***********************************************************************************************

WSDL 說明:

    (Web Services Description Language) 規範是一個描述介面,語義以及Web服務為了響應請求需要經常處理的工作的XML文件。這將使 簡單地服務方便,快速地被描述和記錄。以下是一個WSDL的樣例: My first service

它包含了以下的關鍵資訊: 訊息的描述和格式定義可以通過XML文件中的和 標記來傳送。 標記中表示了訊息傳送機制。 (e.g. request-only, request-response, response-only) 。 標記指定了編碼的規範 。 標記中表示服務所處的位置 (URL)。 WSDL在UDDI中總是作為一個介面描述文件。因為UDDI是一個通用的用來註冊WSDL規範的地方,UDDI的規範並不限制任何型別或者格式描述文件 。這些文件可能是一個WSDL文件,或者是一個正規的包含導向文件的Web頁面,也可能只是一個包含聯絡資訊的電子郵件地址。現在Java提供了一個 Java API for WSDL (JWSDL)規範。它提供了一套能快速處理WSDL文件的方法,並且不用直接對XML文件進行操作,它會比 JAXP更方便,更快速。 ***********************************************************************************************

SOAP說明

    (Simple Object Access Protocal)。 我們先簡單瞭解WebServices運作模式。服務端生成服務描述檔案WSDL(Web Services Description Language,類似COM的Interface Description Language),如果接收客戶端的SOAP請求訊息(XML格式資料),解析其呼叫和引數,根據WSDL和WSML(Web Services Meta Language,Microsoft為描述WSDL裡提供的方法與實現該方法的COM物件之間的對映關係而特地設立),呼叫相應COM物件完成指定功能,並返回 到SOAP訊息遣至使用者;客戶端取得並解析服務端的服務描述檔案從而得知服務端的服務內容及呼叫方式,生成SOAP請求訊息(指定呼叫的方法 名稱和引數)送往服務端。 ***********************************************************************************************

TReomtable說明

    : WebService中自定義類都是繼承自該類 //自己定義一個繼承自TRemotable的類 (注意只有屬性定義,沒有方法) TSpeciesInfo = class(TRemotable) private FLength: Integer; FSpeciesName: string; FCategory: string; FCommonName: string; FmoreInfo: string; published property Category: string read FCategory write FCategory; property CommonName: string read FCommonName write FCommonName; property SpeciesName: string read FSpeciesName write FSpeciesName; property Length: Integer read FLength write FLength; property MoreInfo: string read FmoreInfo write FMoreInfo; end;

TSOAPAttachment說明

    :一種Soap的流型別資料.跟平時的integer等等一個意思 //比如

     (1):伺服器端建立一個流輸出(result:) GrapStream:=TMemoryStream.create; try SoapAttachment:=TSoapAttachment.create; TBolbField(frmdm.adoqury.fields[0]).SaveToStream(GrapStream); SoapAttachment.SetSourceStream(GraphStream,soReference); result:=SoapAttachment; except if assigned(GrapStream) then GrapStream.free; if assigned(SoapAttchament) then SoapAttchment.free; end

    (2):客戶端接受一個流輸入 var src:string; begin if not Assigned(SoapAttachment) then exit; Src:=SoapAttachment.CacheFile; ....

例子,基於Soap和webService的分散式網路程式例項

   //編寫伺服器端 --ok

    1:File --->New---->Other----->WebService--->Soap WebService Application 後生成3個元件 一個是呼叫者元件:THTTPSoapPascalInvoker:完成Soap訊息和.... 一個是排程者元件:THTTPSoapDispatcher:自動響應送入的soap訊息,並且把他們傳遞給呼叫者,可以使用他的 WebDispatch屬性來識別應用程式響應的http請求.包括設定PathInfo屬性來指明指向應用 程式的任何URL的路徑部分,設定MethodType屬性來指明請求訊息的方法頭. 一個是WSDL釋出者:TWSDLHTMLPublisher:WSDL釋出者釋出描敘介面以及如何呼叫他們的wsdl文件,使用非delphi 編寫的客戶端程式也可以呼叫WebService應用程式.

    2:在介面中新增方法和在實現該介面的類中實現該方法. (1):介面中自定義的類都是繼承自TRemotable類,該類只能有屬性,沒有方法 (2):

   3:將生成的Dll檔案拷貝到 C:/InetPub/Scripts目錄下面.

//編寫客戶端 --ok

    (1):File--->New--->other---->WebSerice--->Wsdl Importer: 對話方塊1:WsDl Source:輸入==>http://伺服器名/scripts/應用程式名/wsdl/相應介面 ,然後Next下步.然後點finish

    (2):新增一個普通的窗體,上面放WebService中的控制元件:HTTPRIO,編寫它的OnAfterExecute ,OnBeforeExecute事件 連線服務:http://server/script/MyWebService.dll/Soap/ImyWeb ***請注意是Soap/介面 FAttachService為WebService的介面 if FAttachService = nil then begin FAttachService := GetiMyWeb(False, EditUrl.Text); (FAttachService as IRIOAccess).RIO.OnBeforeExecute := HTTPRIO1BeforeExecute; (FAttachService as IRIOAccess).RIO.OnAfterExecute := HTTPRIO1AfterExecute; end; Result := FAttachService; ******************************************************************************* (HTTPRIO1 as ITest).TestFunction(aParam, bParam);

    (3):注意在IIS中設定Script的是否有執行許可權.

編寫一個基於Soap DataModule的三層資料庫應用

    伺服器端:

    建立一個Web App Debugger executable型別,不需要介面,新增一個Soap Data Module,放上AdoCon,AdoDataSet,DataSetProvider1 設定資料好連線,利用AdoDataSet開啟一個數據集,然後編譯執行,開啟Web App Debugger檢視是否正確.

客戶端:

    (1)建立一個普通的應用程式,新增SoapConnection1元件,設定他的url:格式為:http://localhost:1024/Demo3.wadSoapDemo3/soap

    (2)新增一個ClientDataSet 設定它的RemoteServer=SoapConnection1,provideName=DataSetProvider1 (注意將Web App Debugger開啟) (3)Active就可以看到資料了.

WebService的伺服器端的除錯

    (1):編寫伺服器時選擇:Web App Debugger executable型別

    (2):編寫完成後執行一次伺服器,則系統將把該webservice的類註冊   

    (3):啟動Tool--->Web App Debugger,設定servers的options port============1024 default url=====http://localhost:1024/Demo3.wadSoapDemo3/wsdl 其中demo3為exe程式的名字, wadSoapDemo3為建立伺服器的時 候填寫的類名稱,可在主Form的initialization中找到:TWebAppSockObjectFactory.Create('wadSoapDemo3')

    (4)開啟ie,在地址輸入:http://localhost:1024/Demo3.wadSoapDemo3/wsdl就可以檢視介面了