Il corso sta volgendo al termine. Prima di lasciarci, vorrei, a completamento, mostrare alcune funzionalità di Delphi che permettono la realizzazione di applicazioni indirizzate al web, alla produzione di pagine HTML e che permettono addirittura di creare componenti ASP da inserire nei siti web oppure per creare siti completamente basati su Delphi.
Con Delphi è possibile realizzare applicazioni CGI oppure ISAPI. Il tutto è ovviamente semplicissimo come del resto qualsiasi operazione in Delphi!?! Esistono anche qui dei template da utilizzare per la creazione di CGI, ISAPI e componenti ASP; basta effettuare la scelta giusta nel wizard "New" dal menu "File". Esistono anche dei componenti chiamati "HTML Producer Components" che permettono di creare pagine
HTML.
Questi componenti utilizzano come schema per le pagine da costruire dei template HTML e ricavano i dati per completarli o direttamente dal codice oppure da tabelle di database o query. Questi componenti si trovano nella pagina Internet della Component Palette e sono: PageProducer
, DataSetPageProducer
, DataSettableProducer
, QuerytableProducer
.
Nella pagina Internet della Component Palette oltre ad altri componenti che riguardano internet (WebDispatcher
, WebBrowser
) compaiono i componenti per la produzione di pagine Web: PageProducer, DataSetPageProducer, DataSettableProducer, QuerytableProducer. La tecnica utilizzata da questi componenti per creare pagine HTML è quella di utilizzare un normale file HTML, creato con un qualsiasi editor HTML, contenente alcuni tag speciali che hanno lo scopo di fare da segnaposto per l'output dei dati che l'applicazione dovrà inserire nel documento.
Il formato di questi tags è <#NomeTag>
.
Il componente più semplice, è il PageProducer. Questo analizza il documento HTML che gli viene fornito come template e genera un evento OnTag per ogni tag speciale incontrato in esso. Nell'event handler del evento OnTag deve essere inserito il codice che reagirà al particolare tag. Per esempio se nel nostro documento HTML abbiamo inserito il tag speciale <#Data>, quando il componente analizzerà il documento genererà l'evento OnTag. Il tipo dell'event handler per questo evento è il seguente
Procedure (Sender : TObject; Tag : TTag; const TagString : String; TagParams : TStrings; var ReplaceText : String);
Supponiamo di aver creato il seguente event handler
procedure TForm1.PageProducer1HTMLTag(Sender: TObject; Tag: TTag; const TagString: String; TagParams: TStrings; var ReplaceText: String);
begin
If TagString = 'Data' then
ReplaceText := DateToStr(Now);
end;
Il codice dell'event handler sostituirà il il tag speciale con la data corrente. Supponendo che il nostro documento avesse avuto la seguente struttura
<html>
<head>
<title>Prova componente Page Producer</title>
</head>
<body>
<h2>Data corrente</h2>
La data corrente è <#Data>
</body>
</html>
il risultato sarebbe
Data Corrente La data corrente è 17/08/2001
Il risultato precedente è prelevabile dalla proprietà Content del componente (di tipo TStrings). Esso può essere copiato in un componente memo per la visualizzazione oppure salvato su disco con la proprietà SaveToFile della classe TStrings. L'esempio riportato è semplicissimo, ma è possibile realizzare pagine web complesse attingendo da database o altre fonti.
DataSettableProducer, QuerytableProducer
A proposito di databases, Delphi dispone già di un componente specializzato nella composizione di pagine HTML attingendo da fonti dati quali databases. Questo componente è DataSetPageProducer.
L'utilizzo di questo componente è semplicissimo e molto simile al PageProducer che abbiamo visto sopra. In questro caso abbiamo una proprietà in più che è quella che definisce il collegamento con il dataset contenente i dati. Basta fornire il solito documento HTML come template e disporre dove necessario i tags speciali corrispondenti ai nomi dei campi del dataset collegato al componente stesso. In questo modo il componente recupera automaticamente il contenuto dei campi e lo inserisce nel documento. Noi non dobbiamo fare nulla se non gestire altri tags speciali, come abbiamo fatto nell'esempio precedente, per inserire valori non provenienti dal dataset attraverso il gestore dell'evento OnTag.
Un altro componente per la produzione di codice HTML è il DatasettableProducer che ha lo scopo di creare tabelle in standard HTML prelevando il contenuto da un dataset. Dispone quindi della proprietà Dataset per il collegamento alla sorgente di dati. Questo componente è dotato anche di un "Property Editor" per la proprietà Columns.
Attraverso di esso è possibile impostare a design-time le caratteristiche delle colonne ed i campi del dataset ad esse associati, producendo anche una anteprima del risultato finale. Il DatasettableProducer prevede anche la possibilità di definire un header ed un footer (una intestazione tabella ed un pie' tabella). tramite le proprietà Hader ed Footer del componente è possibile inserire, ad esempio, il titolo del documento.
Il contenuto della proprietà Header e Footer deve essere in formato HTML. Per cui, se volessimo definire il titolo del documento, dovremmo scrivere nella proprietà Header il seguente testo:
<h1>Titolo</h1>
Lo stesso dicasi per la proprietà Footer. Nel componente sono previste anche proprietà per impostare le caratteristiche della tabella quali il colore di sfondo, il cellpadding (la distanza del contenuto della cella dal bordo cella), il cellspacing (lo spazio tra una cella e l'altra), la presenza o no del bordo e la dimensione, e le caratteristiche delle righe che comporranno la tabella. Tutte questa impostazioni sono raccolte in due proprietà, RowsAttributes e tableAttributes. Il componente DatasettableProducer espone anche degli eventi che permettono un maggiore adattamento alle proprie necessità. In particolare l'evento OnFormatCell che viene attivato al momento della formattazione della singola cella. Definire un gestore per questo evento permette di modificare per ogni singola cella i valori di colore di sfondo, l'allineamento verticale od orizzontale, e perfino il contenuto della cella stessa.
In maniera del tutto simile funziona il componente QuerytableProducer tranne per il fatto che questo viene collegato ad un componente Query e che il suo scopo è quello di generare pagine HTML basate su query parametrizzate i cui parametri vengono ottenuti da una richiesta HTML. La modalità di richiesta può essere GET o POST.
Delphi e HTML dinamico
Quanto visto sopra è applicabile ad applicazioni che vogliono fornire una versione dei dati in formato HTML (formato multipiattaforma) o per applicazioni che realizzano server web o servizi che rispondono come server web. Ci sono altri sistemi che possono essere utilizzati per fornire informazioni in formato HTML. Chi realizza siti web conosce i CGI (Common Gateway Interface). Questi vengono utilizzati per fornire pagine HTML dinamiche ovvero il cui contenuto vari in corrispondenza del variare dei potenziali dati da visualizzare.
Esempi di questo tipo di documenti potrebbero essere pagine che forniscono notizie dell'ultima ora, estrazione di dati data database che vengono aggiornati frequentemente (annunci di compra/vendita). Quello che il browser riceve è sempre un documento HTML che altro non è che il prodotto di una elaborazione effettuata dal server web al momento della richiesta compilando la pagina con i dati richiesti e disponibili in quel momento.
Un CGI altro non è che una applicazione eseguibile che risponde alle richieste HTML effettuate dai browser; esso analizza le richieste in arrivo e restituisce dei documenti HTML compilati in base alle richieste ricevute. Esistono due tipi di CGI; i CGI e i WINCGI. I primi ricevono i parametri di richiesta direttamente dalla riga di comando mentre i secondi li estraggono da un file .INI che viene passato loro come parametro nella riga di comando e utilizzano come input ed output speciali files.
Questo secondo tipo di CGI è stato realizzato per venire incontro agli sviluppatori Visual Basic permettendo di scavalcare alcune limitazioni del linguaggio.
Neanche a farlo a posta Delphi ci permette di realizzare questo tipo di applicazioni partendo dalla considerazione che essi non sono altro che applicazioni console che utilizzano lo standard input e lo standard output per acquisire le richieste e fornire i risultati dell'elaborazione. Tutto ciò si traduce in una serie di Writeln che restituiscono codice HTML come ad esempio la seguente riga
Writeln('<h1>Titolo</h1>');
Se eseguiamo il CGI da una finestra di terminale vedremo esattamente ciò che è riportato come parametro nei comandi Writeln.
Oltre ai CGI in Delphi è possibile creare delle DLL ISAPI (Intrenet Server API) o NSAPI (Netscape Server API). Il primo tipo è stato introdotto da Microsoft, mentre il secondo dall Netscape. Questa tecnologia può essere vista come un miglioramento del CGI.
Essa si differenzia dal CGI per le modalità di caricamento nella memoria del server e per le modalità di risposta. Mentre il CGI viene caricato ad ogni richiesta, per questo tipo di DLL le cose cambiano. La DLL viene carica al momento della richiesta, se essa non è già stata caricata in precedenza, nello stesso spazio di indirizzamento del server web ed è capace di rispondere a più richieste facendo uso di threads. Ciò permette di non dover caricare tanti eseguibili in memoria quante sono le richieste fatte al server web come invece accade per i CGI. Ogni thread attivato dal server web gestisce una richiesta e la relativa risposta. C'è differenza anche nella velocità di risposta rispetto al CGI poichè nel caso delle DLL ISAPI/NSAPI lo scambio dei dati avviene tutto in memoria.
Non mi dilungherò oltre su questo argomento. Diamo uno sguardo a cosa mette a disposizione Delphi per aiutarci nella realizzazione di questo tipo di software. Delphi 5 include, nelle versioni Professional e Enterprise, la tecnologia WebBroker che integra nella VCL delle classi che semplificano la realizzazione di applicazioni web lato server.
Per utilizzare il framework WebBroker, è necessario scegliere dal menu file la voce New e nella prima pagina della finestra che compare scegliere "Web Server Application". Ciò provocherà la visualizzazione di una finestra di scelta del tipo di applicazione che si ha intenzione di realizzare.
I tipi di applicazioni tra cui si può scegliere sono tre: DLL ISAPI/NSAPI, eseguibile CGI , eseguibile WinCGI. Nel caso si scelga si realizzare DLL ISAPI/NSAPI, Delphi produrrà un file progetto di libreria del tutto simile ad una normale libreria ma con delle particolarità. Per prima cosa vediamo comparire nella clausola uses del file progetto le unit WebBroker, ISAPIApp ed una nuova unit che contiene un oggetto WebModule. Nello stesso tempo dalla libreria vengono esportate delle procedure standard per il caricamento e scaricamento della libreria nella/dalla memoria del server web.
Da notare che in questo tipo di DLL, l'oggetto application che viene creato non è di tipo standard, non corrisponde infatti agli altri oggetti application creati nelle normali applicazioni.
Nelle applicazioni ISAPI/NSAPI, l'oggetto application deriva da una nuova classe che può essere TISAPIApplication o TCGIApplication.
Queste ultime derivano entrambe da un'altra classe che è TWebApplication. Sono delle classi specializzate per la realizzazione di applicazioni per il Web.
Il tipo dell'oggetto applicazione può essere TISAPIApplication o TCGIApplication in base alla scelta che abbiamo effettuato nel wizard del Object Repository. La caratteristica più importante è che l'intera applicazione ruota attorno alla nuova unit contenente l'oggetto WebModule.
Un WebModule è molto simile ad un DataModule standard, con ovviamente delle caratterizzazioni specifiche per le applicazioni web. Il WebModule ha lo scopo di raccogliere tutti gli oggetti non visuali dell'applicazione e di permettere ad essa di rispondere ai messaggi di richiesta HTTP passando gli oggetti Request e Response alle azioni appropriate.
Tra le proprietà dell'oggetto WebModule compare la proprietà Actions. Essa contiene l'elenco delle azioni che devono essere eseguite dall'applicazione in risposta ad un determinato switch che viene passato alla
DLL. Lo switch che identifica l'azione è contenuto nella proprietà PathInfo dell'oggetto WebAction stesso.
Un'altra proprietà interessante dell'oggetto WebAction è Producer che permette di collegare all'azione direttamente un oggetto di tipo TPageProducer, tdataSetPageProducer, tdatasettableProducer, TQuerytableProducer (che abbiamo già visto) che verrà richiamato all'attivarsi dell'azione stessa.
Un'altra tecnologia che permette di realizzare pagine HTML dinamiche, è la tecnologia ASP (Active Server Pages) introdotta da Microsoft. Essa si basa su codice script, inserito all'interno di documenti HTML, che viene eseguito direttamente nel server e che produce pagine HTML standard in risposta alle richieste dei clients. Questa tecnologia prevede anche un estensione delle proprie funzioni attraverso la realizzazione di oggetti COM che possono essere richiamati direttamente dal codice script. Anche in questo caso Delphi ci viene incontro fornendoci la struttura base per la realizzazione di questo tipo di componenti. Nel wizard che porta alla realizzazione del codice base per la realizzazione di oggetti ASP possiamo impostare tutti i parametri di funzionamento dell'oggetto COM, come il nome della classe, il tipo di interfaccia ed il tipo di threading dell'oggetto, il tipo di oggetto.
Per creare la struttura base di un oggetto ASP, possiamo scegliere dal menu File -> New, nella pagina ActiveX dell'Object Repository la voce Active Server Object.
ATTENZIONE! Per poter creare un oggetto ActiveX bisogna disporre di un progetto attivo, nel nostro caso potremmo creare un progetto di tipo "ActiveX Library", sempre dall'Object Repository, e quindi seguire la procedura indicata precedentemente.
Il wizard ActiveX Server Object presenterà una finestra per l'inserimento delle caratteristiche principali dell'oggetto ActiveX come riportato nell'immagine seguente
Fig.1
CoClass Name indica il nome dell'oggetto ActiveX che si sta creando a cui Delphi anteporrà un T; per cui se inseriamo in questa casella "ProvaASP" il nome della classe che sarà "TProvaASP".
Instancing definisce la modalità di istanziazione dell'oggetto ovvero Internal, Single Instance, Multiple Instance. Nel primo caso l'oggetto sarà creato come interno e nessun'altra applicazione potrà creare un'altra istanza dello stesso. Single Instace permette di creare una singola interfaccia per l'oggetto COM per ciascun eseguibile. Multiple Instance permette invece a più applicazioni di collegarsi all'oggetto.
Threading Model specifica invece la modalità di gestione dei thread dell'oggetto COM. L'impostazione Single indica che non vi è nessun supporto per i thread e che tutte le richieste dei clients vengono gestite in maniera seriale.
Apartment permette di accedere alle proprietà ed ai metodi dell'oggetto solamente attraverso il thread in cui è stato creato l'oggetto stesso. Free le proprietà ed i metodi possono essere chiamati in qualsiasi momento da qualsiasi thread.
La modalità Both indica che l'oggetto in questione può supportare il metodo Apartment e Free.
Active Server Type definisce la "compatibilità" con il server web specifico: IIS3 o 4 per l'opzione Page-level event methods e IIS 5 per Object Context. In pratica, nel primo caso vengono generati all'interno dell'oggetto due eventi OnPageStart, OnPageEnd che vengono richiamati dal server web rispettivamente all'inizializzazione della pagina e al termine dell'elaborazione. Nel secondo caso vengono utilizzate le funzionalità di MTS per recuperare i dati di istanza corretti dell'oggetto.
Nel riquadro Options, se viene spuntata la voce "Generate a template test script for this object", verrà cerata una pagina asp che istanzierà e utilizzerà l'oggetto creato ed ha solamente scopo di test.
Una volta creata la struttura base del nostro oggetto ASP, è possibile accedere direttamente agli oggetti Application, Response, Request, Session di ASP. Non resta che implementare il codice specifico. Vediamo un semplicissimo esempio.
A questo punto proviamo ad aggiungere un semplice metodo al nostro oggetto. Esso avrà solamento lo scopo di restituire nel flusso HTML di risposta del codice HTML. Aggiungiamo alla nostra alla classe appena creata una procedura così definita
procedure ShowHelloASP; safecall;
ed implementata nel seguente modo
procedure TProvaASP.ShowHelloASP;
begin
Response.Write('<h1>Prova oggetto ASP in Delphi</h1><br />');
Response.Write('<strong>Hello ASP!!!</strong>');
end;
Ora dovremo inserire una chiamata al metodo del nostro oggetto dalla pagina asp di test (magari creata automaticamente da Delphi) ottenendo quanto segue:
<html>
<body>
<title>Testing Delphi ASP</title>
<h3> You should see the results of your Delphi Active Server method below</h3>
<hr />
<%
Set DelphiASPObj = Server.CreateObject("HelloASP.ProvaASP")
DelphiASPObj.ShowHelloASP
%>
<hr />
</body>
</html>
Questo è solo un esempio, ma in programmazione (e soprattutto in Delphi) i limiti sono quelli posti dalla nostra immaginazione!
P.S. Ovviamente per approfondimenti sull'argomento trattato, consultate il manuale del linguaggio, la guida in linea e se ne avete la possibilità "Mastering Delphi 5" di Marco Cantù.