Hlavní navigace

Kylix (7) - webové služby

28. 5. 2002
Doba čtení: 12 minut

Sdílet

Dnes si něco povíme o implementaci klientů a serverů pro webové služby za pomoci SOAP. Dále si ukážeme klient, který bude překladačem z angličtiny do francouštiny za pomoci čtyř komponent a bude využívat webovou službu. Zmíníme, co je to WSDL, no a nakonec si nějakou webovou službu napíšeme (je libo CGI, nebo modul Apache - nám je jedno). A jelikož jsem dostal půjčený Kylix 2 Enterprise, uděláme malou recenzičku a ukážeme, co nám může přinést. Dnes se prostě máte na co těšit.

Kylix 2 Enterprise – první dojmy

Co tedy za své těžce vydřené peníze dostanete?

Nejdříve na mne vybafla registrační karta a nějaké reklamy. První užitečnou věcí je plakát s barevně odlišenou (podle edicí) objektovou hierarchií CLX formátu A0. Škoda, že mi už nad stolem visí mapa Zeměplochy…

V krabici jsem dále našel tři manuály. Jejich elektronická (pdf) podoba je na CD a nainstaluje se s Kylixem (tištěné manuály jsou součástí i verze Professional).

  • Quick Start – jednoduchý úvod do programování ve všech oblastech (94 stran) – elektronická verze je i v Open Edition (pdf)
  • Language Quide – kompletní popis Object Pascalu (250 stran)
  • Developer Quide – příručka vývojáře rozdělená do čtyř sekcí (800 stran)
    Programming with
    Kylix Developing database applications
    Writing Internet applications
    Creating custom components

A teď to nejdůležitější 4 CD:

  • Kylix 2 Enterprise – toť to, oč tu běží, na CD je zároveň InterBase 6 (verze 6.0.1, tj. bez toho pevného účtu, ale raději si to vyzkoušejte nebo použijte Firebird)
  • Kylix 2 – Companion tools – CD, které obsahuje různé komponenty a dokumenty třetích stran (některé i zajímavé, třeba konverze hlaviček SDL i s demy do Object Pascalu)
  • Delphi 6 Enterprise Trial
  • Demo výukového programu na web aplikace v Delphi a Kylixu (ale pro Windows). Nicméně AVI jsem přehrál MPlayerem a texty jsou v HTML.

Instalace

Jelikož už jsem měl nainstalovánu Open Edition, tak jsem Enterprise nainstaloval jako normální uživatel (nerootovská instalace). Kompletní instalace zabírá kolem 250 MB (z toho mozilla preview widget asi 15 MB). Tento widget se používá pro náhled HTML stránek vytvořených pomocí WebSnap přímo v IDE. Poznámka: pro srovnání Open Edition má asi 100 MB.

Co to tedy umí?

Na rozdíl od verze Professional, která je primárně určena pro vývoj databázových a GUI aplikací (podnikové informační systémy), je verze Enterprise primárně určena jako vývojové RAD prostředí pro e-business aplikace (s důrazem na XML, SOAP atd.) a webové aplikace vůbec (včetně DB).

Rozšíření lze rozdělit do několika částí:

  • BizSnap – vyžití webových služeb na bázi XML
     – využití SOAP (Simple Object Access Protocol) ke komunikaci
     – spolupráce s platformami MS .Net, SUN ONE
     – XML transformace (datová množina ↔ XML, XML ← >)
     – XML jako nativní objekty Kylixu
  • WebSnap – platforma pro webové aplikace
     – cílem překladu může být CGI nebo modul pro Apache
     – XSL Page Producer kombinuje XML zdrojová data a XSL transformaci do výsledné HTML stránky
     – podpora Java skriptů na straně serveru
  • DataSnap – databázová střední vrstva pro webové služby
     – za podpory SOAP lze přistupovat k velkým databázím
     – tvorba XML/SOAP rozhraní webových služeb
  • Corba – vývoj klientů i serverů
  • doplnění dbExpress
     – drivery pro Oracle, DB2 a Informix
     – SQL monitor a SQL Builder

Jak Professional, tak Enterprise obsahují WebBroker, což je multiplatformní podpora pro vytváření aplikací webového serveru – o něm se zmíním dnes a o WebSnap příště (WebBroker je podmnožinou WebSnap).

Nové věci v IDE

Jak ve verzi Professional, tak Enterprise je rozšířený editor (o změnách jsem již psal).

V edici Enterprise navíc přibyl nástroj XML Mapper, který umožňuje kromě jiného konverzi dat z XML a dat pro DataSet (v různých kombinacích).

V menu File – New přibyli noví Wizardi: Web Server Application, Web Snap Application, Web Snap Data Module, Web Snap Page Module, XML Data Binding, SOAP Server Application, SOAP Data Module, Web Service Importer, Corba Client, Corba Server.

K některým se dostaneme blíže. Začneme klientem pro webovou službu via SOAP.

Vytvoření klienta pro připojení k externí webové službě (client)

Na adrese www.xmethods.net je seznam registrovaných webových služeb, které jsou veřejně dostupné pro účely testování. Pokud budete procházet seznamem publikovaných služeb, zjistíte, že vývojová prostředí použitá pro implementaci jsou různá a jdou napříč platformami (je tam i Delphi a Kylix).

V seznamu najdeme službu AltaVisty Babel Fish, která umožňuje překlad textu. Prozkoumáním informací zjistíme např. jména metod a také cestu k souboru WSDL, který službu popisuje: www.xmethods.net/sd/2001­/BabelFishSer­vice.wsdl.

Poznámka: WSDL je zkratka pro Web Service Definition Language a jako formát používá XML.

Uživatelské rozhraní

Nyní vytvoříme jednoduché uživatelské rozhraní, které bude reprezentovat klienta. Bude sestávat ze dvou memo a tlačítka mezi nimi. Do prvního mema zadáme anglický text a po stisku tlačítka se nám zobrazí přeložený text ve spodním memu.

Vytvoříme novou aplikaci a vložíme uvedené komponenty. Z palety komponent WebServices vybereme nevizuální komponentu THTTPRIO a vložíme ji na formulář. Tato komponenta používá protokol HTTP pro volání vzdálených objektů s definovaným rozhraním za použití technologie SOAP. Komponenta HTTPRIO umožňuje volání definovaných metod skrze tabulku generovanou dynamicky v paměti, která převede volání na požadavek pro SOAP a pošle ho přes HTTP webové službě. Následně dekóduje odpověď pro zpracování v programu. Pokud požadavek vyvolal výjimku serveru, je tato šířena do aplikace.

Poznámka: více o SOAP se lze dozvědět na adrese www.w3.org/TR/SO­AP.

Získání rozhraní webové služby

Nyní musíme získat rozhraní služby Babel Fish, což znamená vytvořit importní unit pro Object Pascal, který bude službu zapouzdřovat a zároveň dovolí kompilátoru typovou kontrolu.

Z menu File – New… vybereme záložku WebServices a v ní Web Services Importer. V dialogovém okně zadáme cestu (nebo adresu) k WSDL souboru www.xmethods.net/sd/2001­/BabelFishSer­vice.wsdl a stiskem Generate vygenerujeme požadovaný soubor.

Poznámka: pokud by byla služba psaná v Kylixu (nebo Delphi), není nutno pro klienta importovat WSDL soubor, ale sdílel by se pouze vygenerovaný unit. WSDL je nutný, pokud vývojové prostředí pro klienta není shodné s prostředím pro server.

Unit Unit2;
interface
uses
  Types, XSBuiltIns;
type
  BabelFishPortType = interface(IInvokable)
    ['{4D613C81-48BB-11D5-8D99-444553540000}']
    function BabelFish(const translationmode: WideString;
      const sourcedata: WideString): WideString;  stdcall;
  end;
implementation
uses
  InvokeRegistry;
initialization
  InvRegistry.RegisterInterface(TypeInfo(BabelFishPortType), '', '');
end.

Vidíme, že bylo vygenerováno rozhraní k webové službě. Nyní stačí přidat jméno vygenerovaného souboru do uses hlavního formuláře.

Nastavení HTTPRIO

Vyberte vloženou komponentu HTTPRIO a nastavte vlastnost WSDLLocation na výše uvedenou cestu k souboru WSDL. Pokud je cesta správná, obsahuje vlastnost Service nabídku služeb (v našem případě BabelFishService) a vlastnost Port nabídku portů (v našem případě BabelFishPort).

V tomto okamžiku je klient připraven na využití uvedené služby.

Poslední věcí je vytvoření obsluhy tlačítka. Změňte u něj popisku na &Translate a do OnClick napište

procedure TForm1.Button1Click(Sender: TObject);
var
  BabelService: BabelFishPortType;
begin
  BabelService:= HTTPRio1 as BabelFishPortType;
  memo2.Text := BabelService.BabelFish('en_fr', memo1.text);
end;

Uvedený kód zavolá službu Babel Fish, kde první parametr značí směr překladu a druhý obsahuje text pro překlad. Návratovou hodnotou je přeložený text, který je vložen do druhého mema.

Spuštění aplikace

Spusťte program, do prvního mema napište nějaký anglický text a po stisku tlačítka Translate by se měl ve spodním okně zobrazit překlad. Pokud ne, udělali jste něco špatně – jste vůbec připojeni k Internetu?

Vytvoření webové služby (server)

V předchozím případě jsem vytvořil klienta, nyní nastal čas na vytvoření serveru. Dlouho jsem přemýšlel, co by byl dostatečně jednoduchý, ale zajímavý příklad. Něco takového, co tady ještě nebylo. No a na nic jsem nepřišel, tak uvedu konverzi stupňů na radiány a zpět. Stejně mi šlo jen o princip. Podobně lze vytvořit jakoukoliv službu.

Vytvoření kostry serveru

Použijeme „wizarda“: Menu File – New.. -Web Service – SOAP Server.

V dalším kroku jsme dotázáni, zda zvolit CGI, nebo modul Apache. Zde si zvolte dle libosti a kostra aplikace je hotova. Obsahuje tři nevizuální komponenty:

  • HTTPSoapDispatcher – zpracovává SOAP příkazy
  • HTTPSoapPasca­lInvoker – vyvolává metody Object Pascalu podle požadavku SOAP
  • WSDLHTMLPublish – při požadavku vygeneruje WSDL soubor, který definuje rozhraní webové služby

Definice rozhraní

Nyní vytvoříme unit, který bude definovat poskytované rozhraní a zároveň toto rozhraní bude registrovat.

unit DegRadInf;

interface
Type
  IDegRad = interface (IInvokable)
    function DegToRad(Deg:Double):Double; stdcall;
    function RadToDeg(Rad:Double):Double; stdcall;
  end;
implementation
uses
  InvokeRegistry;
initialization
  InvRegistry.RegisterInterface(TypeInfo(IDegRad));
end.

Implementace rozhraní

Rozhraní máme definované, tak ho zbývá pouze implementovat.

unit DegRadImpl;
interface
uses
  DegRadInf, InvokeRegistry;
type
  TDegRad = Class (TInvokableClass, IDegRad)
  public
    function DegToRad(Deg:Double):Double; stdcall;
    function RadToDeg(Rad:Double):Double; stdcall;
  end;

implementation
function TDegRad.DegToRad(Deg: Double): Double;
begin
  Result:=PI*Deg/180
end;
function TDegRad.RadToDeg(Rad: Double): Double;
begin
  Result:= Rad*180/PI
end;
initialization
  InvRegistry.RegisterInvokableClass(TDegRad);
end.

Provoz služby

Tímto krokem je služba hotová. Jelikož jsem si na začátku zvolil CGI aplikaci, nahraji výslednou binárku do adresáře Apache pro CGI – služba se jmenuje degrad (jako složení Deg a Rad, rozumíme si?).

Zadáním adresy http://localhos­t/protected-cgi-bin/degrad/wsdl/I­DegRad dostanu WSDL popis mojí služby (zde je výsledek). V tomto okamžiku je má služba dostupná pro klienty napsané v různých vývojových prostředích (WSDL soubor definuje rozhraní).

Pokud by byl klient napsaný v Kylixu nebo Delphi, nebyl by WSDL soubor potřeba, jelikož by stačil unit s rozhraním.

Poznámka: škoda, že nemám k dispozici viditelný linuxový počítač, příklady by mohly být zajímavější.

Vytvoření klienta by bylo podobné jako v prvním případě.

Rád bych ještě poznamenal, že CGI je méně efektivní než modul Apache, jelikož je CGI vždy nutno znovu zavést do paměti (na rozdíl od modulu, který je v paměti přítomen, tudíž si může držet například připojení do databáze). Na druhou stranu se s ním lépe pracuje při vývoji. Nic ale nebrání vyvíjet službu jako CGI, pak změnit soubor dpr (změna se týká asi tak šesti řádků) a přeložit službu jako modul pro Apache. Navíc nic nebrání tomu, mít dva soubory dpr (jeden pro CGI, druhý pro Apache).

WebBroker

WebBroker je název metody, jak vytvářet aplikace pro webový server. Je obsažena jak v Professional, tak v Enterprise. Navíc je multiplatformní, takže pokud zákazník zmámený reklamou odmítne Linux, prostě aplikaci přeložíte v Delphi a je vystaráno.

Jako cíl je možno zvolit CGI, nebo modul pro Apache a platí to samé, co jsem uvedl výše (předchozí server je v podstatě postaven nad WebBrokerem).

Teď se určitě ptáte, proč bych měl pro vývoj těchto aplikací používat Kylix, když tu je PHP, Perl, Java, ASP atd. Tady se pouštím na tenký led a nemusíte se mnou souhlasit.

Všimněte si, že ačkoliv máme rychlejší sítě, je odezva na většině serverů čím dál horší. Můj osobní názor je, že pokud se jedná o málo exponovaný server – tak klidně interpretované jazyky. Nevadí, že bude odezva trochu pomalejší. Pokud se ale jedná o větší server se složitějším rozhraním, tak podle mne jedině kompilované jazyky. No a teď pouze vybrat ten jediný správný. Příkladem může být www.abclinuxu.cz, kde autor používá Javu a je to poznat. Ale dosti horké půdy.

Nový server

Jako obvykle použijeme wizarda. File – New.. – Web Server. Po již klasické otázce CGI x modul Apache (tady je to ještě jednoduché, ale v Delphi se vybírá z pěti možností…) se vygeneruje kostra aplikace ve formě nevizuálního kontejneru na komponenty WebModule.

Tento modul je jádrem celé aplikace. Zde nadefinujeme „cesty“ k jednotlivým funkcím.

  • /GetTime – zobrazí aktuální čas serveru
  • /Menu – zobrazí nabídku odkazů na /MenuItem (provede se, i když nebudeme specifikovat žádnou službu)
  • /MenuItem – zpracuje vybraný odkaz

Aktuální čas
Ve WebModule přidáme uvedené akce. Pro každou akci musíme specifikovat cestu (vlastnost PathInfo). Pro první akci by bylo URL: www.nekde.cz/cgi-bin/MujServer/Get­Time, kde MujServer je jméno našeho programu a /GetTime je název naší první služby (a přesně toto se uvede do PathInfo). Tímto hlavní program ví, kde má hledat obsluhu. Zároveň nastavíme u druhé služby Default, tj. tato služba bude vyvolána, i když nebude zadána cesta (zobrazí se nabídka).

No a nyní stačí doplnit obsluhu události OnAction pro první akci a naše první služba je hotova (doplnil jsem dva prostřední řádky).

procedure TWebModule1.WebModule1WebActionItem1Action(Sender: TObject;
  Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
  Response.ContentType:='text/html';
  Response.Content:='<HTML><BODY>'+DateTimeToStr(Now)+'</BODY></HTML>';
end;

To nic není, na to nepotřebujeme Kylixe, proto zkusíme něco drsnějšího:

Generování seznamu odkazů

Toto není nic jiného než např. seznam článků na serveru (zatím ovšem bez DB). Jelikož ovšem někdy chceme měnit vzhled, je výhodou nadefinovat šablonu stránky, která se bude pouze vyplňovat. Zde s výhodou použijeme komponentu TPageProducer, která dokáže parsovat data a při výskytu tagu (jakékoliv slovo začínající znakem #) vyvolá událost. Nejdříve šablona (template.htm):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
<TITLE>Demo stránka - jídelníček</TITLE>

<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-2">
</HEAD>
<P>
<H1>Jídelníček</H1>
<BODY >
<#MenuItem>
<P>

Vygenerováno <#GenDate>
</BODY>
</HTML>

Je vidět dva tagy, které se budou měnit. Nyní obsluha události u PageProducer:

procedure TWebModule1.PageProducer1HTMLTag(Sender: TObject; Tag: TTag;
  const TagString: String; TagParams: TStrings; var ReplaceText: String);
const
 cServerPath='/protected-cgi-bin/MujServer';
var
  i:Integer;
begin
if TagString='MenuItem' then
  begin
    ReplaceText:='';
    for i:=1 to 10 do
      ReplaceText:=ReplaceText+format('<a href="%s">%s</a><BR>',
        [cServerPath+'/MenuItem?ID='+IntToStr(i),'Jídlo '+IntToStr(i)]);
  end
else
  if TagString='GenDate' then
    ReplaceText:=DateTimeToStr(Now);
end;

Pokud je nalezen první tag, vygeneruje se 10 odkazů, v druhém případě se vygeneruje aktuální datum. Nesmíme zapomenout nastavit u komponenty jméno HTML souboru na template.htm. To lze samozřejmě i za běhu.

Nyní ještě musíme reagovat na akci přiřazením výstupu z PageProducer.

procedure TWebModule1.WebModule1WebActionItem2Action(Sender: TObject;
  Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
  Response.Content:=PageProducer1.Content;
end;

No a poslední věc je reakce na naše vytvořené odkazy (v reálném světě by se opět pak šahalo do DB, např. podle klíče ID).

procedure TWebModule1.WebModule1WebActionItem3Action(Sender: TObject;
  Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
  Response.ContentType:='text/html';
  Response.Content:='<HTML><BODY>'+' Vybrali jste si menu '+
  Request.QueryFields.Values['ID']+'</BODY></HTML>';
end;

QueryFields je opět typu TStrings. Tak a základ znáte. Nezmínil jsem se o komponentách, které produkují výstup z DB přímo do HTML, nezmínil jsem se o tom, že PageProducer umí Java Skripty atd…

CS24_early

Abych nezapomněl: zdrojové kódy jsou zde.

No a aby zde bylo i něco pro zastánce Open Source, tak na delphree.clex­pert.com je Delphi Open Source iniciativa.

Byl pro vás článek přínosný?