![]() | ![]() |
![]() |
Web Services
Wat was ook al weer een Web Service?
Je kan het zien als een (remote) engine, die in staat is om taken (de methoden) uit te voeren.
Het voordeel is gestructureerd hergebruik van bestaande bouwstenen (die bovendien cross-language en cross-platform kunnen zijn).
De engine wordt benaderd via SOAP (het Simple Object Access Protocol), en de beschrijving van wat de Web Service kan doen wordt gedaan met behulp van de WSDL (Web Service Description Language).
Gelukkig hoeven we daar weinig tot niks van te weten, aangezien Delphi dat allemaal voor ons omzet in leesbare Object Pascal code.
Web Service Engines
Enkele Delphi 6 Web Services (de engines) die ik heb geschreven in Delphi 6 en Kylix 2 zijn reeds beschikbaar voor daadwerkelijk gebruik (zie ook Dr.Bob's SOAP Bubbles), zoals de IHitchHiker, ITicTacToe, IRoman, IDutch, IHeadline en IEuro (zowel in Kylix 2 als Delphi 6).
Met name de IEuro is een handige Web Service die ons instaat stelt om bedragen in de ene munteenheid om te zetten in euros (of terug).
Ik heb deze Web Service zowel in Delphi 6 als in Kylix 2 gebouwd, dus kunnen we kiezen voor gebruik van de Web Service engine onder Windows (als http://www.eBob42.com/cgi-bin/Euro42.exe/wsdl), of onder Linux (als http://www.drbob42.co.uk/cgi-bin/Euro42/wsdl).
Uiteraard werken ze allebei hetzelfde.
Delphi 6.02 Professional
Na toepassing van Update 2 op Delphi 6 Professional, zien we plotseling een extra WebServices tab in het Component Palette (meer hierover straks), en een extra WebServices tab in de Object Repository.
Deze gaan we gebruiken voor onze Web Service Euro Calculator client toepassing.
Doe File | New Application, en bewaar het gegenereerde main form in MainForm.pas, en het project zelf in EuroCalc.dpr.
Doe vervolgens File | New - Other en ga naar de WebServices tab van de Object Repository.
Hier zien we de nieuwe WSDL Importer, die in staat is om van een WSDL definitie (van een Web Service) een Object Pascal import unit te genereren voor ons.
// ************************************************************************ // // The types declared in this file were generated from data read from the // WSDL File described below: // WSDL : http://www.eBob42.com/cgi-bin/Euro42.exe/wsdl/IEuro // Version : 1.0 // (2002-02-24 14:25:54 - $Revision: 1.9.1.0.1.0.1.9 $) // ************************************************************************ // unit IEuro1; interface uses InvokeRegistry, Types, XSBuiltIns; type // ************************************************************************ // // The following types, referred to in the WSDL document are not being represented // in this file. They are either aliases[@] of other types represented or were referred // to but never[!] declared in the document. The types from the latter category // typically map to predefined/known XML or Borland types; however, they could also // indicate incorrect WSDL documents that failed to declare or import a schema type. // ************************************************************************ // // !:string - "http://www.w3.org/2001/XMLSchema" // !:double - "http://www.w3.org/2001/XMLSchema" // ************************************************************************ // // Namespace : urn:Euro-IEuro // soapAction: urn:Euro-IEuro#%operationName% // transport : http://schemas.xmlsoap.org/soap/http // style : rpc // binding : IEurobinding // service : IEuroservice // port : IEuroPort // URL : http://www.eBob42.com/cgi-bin/Euro42.exe/soap/IEuro // ************************************************************************ // IEuro = interface(IInvokable) ['{3D819D7A-85D1-4490-75D7-61CC7232A91E}'] function FromEuro(const Currency: String; const Amount: Double): Double; stdcall; function ToEuro(const Currency: String; const Amount: Double): Double; stdcall; end; function GetIEuro(UseWSDL: Boolean=System.False; Addr: string=''): IEuro; implementation uses SOAPHTTPClient; function GetIEuro(UseWSDL: Boolean; Addr: string): IEuro; const defWSDL = 'http://www.eBob42.com/cgi-bin/Euro42.exe/wsdl/IEuro'; defURL = 'http://www.eBob42.com/cgi-bin/Euro42.exe/soap/IEuro'; defSvc = 'IEuroservice'; defPrt = 'IEuroPort'; var RIO: THTTPRIO; begin Result := nil; if (Addr = '') then begin if UseWSDL then Addr := defWSDL else Addr := defURL; end; RIO := THTTPRIO.Create(nil); try if UseWSDL then begin RIO.WSDLLocation := Addr; RIO.Service := defSvc; RIO.Port := defPrt; end else RIO.URL := Addr; Result := (RIO as IEuro); finally if Result = nil then RIO.Free; end end; initialization InvRegistry.RegisterInterface(TypeInfo(IEuro), 'urn:Euro-IEuro', ''); InvRegistry.RegisterDefaultSOAPAction(TypeInfo(IEuro), 'urn:Euro-IEuro#%operationName%'); end.Deze code is geheel nieuw (ten opzichte van de code die eerder werd gegenereerd), en biedt ook meer ondersteuning dan er vóór Update 2 van Delphi 6 beschikbaar kwam. We kunnen nu namelijk de function GetIEuro aanroepen om het interface op te halen en meteen te gebruiken. We hoeven dus niet langer zelf een HTTPRIO component te gebruiken (van de WebServices tab van het Component Palette), alhoewel deze mogelijkheid natuurlijk nog wel beschikbaar is voor wie de HTTPRIO component van de WebServices tab zelf wil gebruiken (de andere twee zijn niet eens nodig voor dit voorbeeld):
procedure TForm1.BtnFromEuroClick(Sender: TObject); begin EditOutput.Text := FloatToStr((HTTPRIO1 AS IEuro).FromEuro( RadioGroupCurrency.Items[RadioGroupCurrency.ItemIndex], StrToFloat(EditInput.Text))) + #32 + RadioGroupCurrency.Items[RadioGroupCurrency.ItemIndex]; end;Het alternatief (voor het gebruik van de HTTPRIO component), en nieuw in Update 2 van Delphi 6, is het gebruik van de gegenereerde function GetIEuro. Deze heeft twee default argumenten (die bepalen of we de URL of de WSDL gebruiken), en geeft direct het IEuro interface terug. Het aanroepen van de ToEuro methode in de OnClick event handler van de ToEuro button gaat daarmee als volgt:
procedure TForm1.BtnToEuroClick(Sender: TObject); begin EditOutput.Text := FloatToStr(GetIEuro.ToEuro( RadioGroupCurrency.Items[RadioGroupCurrency.ItemIndex], StrToFloat(EditInput.Text))) + ' EUR' end;In beide gevallen gaat het gebruik van het IEuro interface hetzelfde. maar de nieuwe function GetIEuro maakt het gebruik van de Web Service nog eenvoudiger dan hiervoor, omdat we nu niet langer een expliciete HTTPRIO component nodig hebben!
Meer Informatie
Mocht iemand nog vragen, opmerkingen of suggesties hebben, dan hoor ik die het liefst via .
Wie meer wil weten over XML, SOAP en het gebruik (en de bouw) van Web Services moet zeker eens overwegen om zich in te schrijven voor mijn Delphi Clinic over BizSnap.