mercoledì 12 dicembre 2007

Tutorial Ajax - Capitolo 3

Introduzione




Il nostro Ajax Engine ci permette di recuperare i dati dal web server sotto forma di codice html preformattato, oppure come risultato dell’elaborazione di pagine dinamiche scritte magari in JSP oppure in ASP.NET.

Quando si sviluppano web applications complesse ci si ritrova a dover gestire probabilmente qualche decina di interfacce grafiche diverse, collegate ad una pagina principale a cui l’utente accede previa autenticazione e sceglie quale servizio utilizzare tra l’insieme di servizi disponibili all’interno dell’applicazione.

A questo punto chi progetta l’applicazione puo’ in teoria decidere di creare un unico documento il cui contenuto puo’ venire azzerato e reinizializzato per ogni diverso servizio senza ricaricare la pagina che agisce ora solo come contenitore esterno.



Facciamo un semplice esempio per illustrare questo scenario.


Questa e’ una pagina html. Molto semplice e nemmeno il massimo dal punto di vista stilistico. E sicuramente chiunque sarebbe in grado di farla meglio. Pero’ e’ una pagina funzionante. Carica un file contenente le istruzioni di formattazione CSS ed il nostro ajax engine prima di istanziare tre contenitori – i layer- e richiamare la funzione initPage() contenuta nell’engine.

Se la funzione di inizializzazione non eseguisse nessuna operazione al suo interno, questa pagina sarebbe un bel documento vuoto agli occhi dell’utente che vuole visualizzarlo sul proprio browser.



Se pero’ riempissimo di volta in volta i tre contenitori con il contenuto necessario , dislocandoli in posti diversi grazie al file CSS?



Potremmo ad esempio creare un piccolo form all’interno del primo layer:




Se in un file remoto form.html contenesse solo il codice iniziale che vediamo sopra, e lo inserissimo nel primo layer sfruttando il metodo innerHTML, sul nostro browser apparirebbero un campo di inserimento testo, una lista a tendina ed un bottone. Ovvero l’utente vedrebbe gli oggetti che costituiscono il nostro form.

Immagino che a questo punto la strada che voglio seguire si intraveda chiaramente. Con un set di documenti html preformattati, come si trattasse delle tessere di un puzzle, possiamo comporre interfacce grafiche complesse in modo arbitrario, con effetti interessanti ed inediti finora dal punto di vista dell’interattiviita’.

Nel nostro esempio, una volta inserito il nome della citta’ possiamo intercettare l’evento che indica il cambiamento del testo visualizzato per precaricare i codici postali associati in modo trasparente. Solo quando avremo digitato una citta’ riconosciuta caricheremo - pressoche’ in tempo reale e senza che l’utente se ne accorga - solo i suoi CAP corrispondenti nella lista:





La giungla dei fornitori dati

Utilizzando l’impostazione appena vista si puo’ gia’ progettare una web application aziendale su un’unica pagina web. Se pero’ si devono organizzare piu’ servizi e si devono inserire piu’ oggetti nella nostra interfaccia grafica i cui dati (o stati) cambiano a seconda dell’interazione che si ha con l’utente, si puo’ arrivare a dover creare innumerevoli fornitori dati, ovvero documenti html preformattati o pagine dinamiche che restituiscano la porzione di codice html da inserire negli elementi sulla GUI.

Per migliorare un poco la situazione si possono accorpare piu’ oggetti in un fornitore dati.

Se cioe’ avessimo molti oggetti in un form e ognuno di essi deve essere inizializzato con i suoi dati, allora creeremo una pagina dinamica unica che dara’ come risultato il form con gli elementi valorizzati, da collegare al contenitore/layer opportuno. E non avere un fornitore per l’inizializzazione di ogni oggetto.




Ora pero’ dobbiamo dare uno sguardo a come formattare i dati restituiti dai nostri fornitori dati oltre all’html, perche’ spesso avremo la necessita’ di richiedere al web server solo un dataset senza l’html di contorno. Il formato XML
Se ci soffermiamo su AJAX inteso solamente come acronimo, notiamo che l’ XML assume un ruolo rilevante essendo indicato come formato di trasporto dei dati. In realta’ e’ scorretto pensare che l’ XML sia intrinsecamente legato ad Ajax inteso come approccio di progettazione web. Ma comunque puo’ esere utilizzato come formato di output per le richieste Ajax.

XML sta per eXtensible Markup Language, ovvero Linguaggio a Markup estesi.
Si tratta quindi di un linguaggio a markup di tipo generico che puo’ essere utilizzato per descrivere praticamente qualsiasi cosa. L’XML differisce dagli altri linguaggio a markup come l’SGML e l’ HTML per il fatto che non e’ vincolato ad un vocabolario di markup o tag.

Percio’ l’autore di un documento XML e’ libero di utilizzare qualunque termine voglia come marcatore per i tag. L’unica prescrizione e’ che il documento segua alcune regole semplici che pero’ non sono collegate al vocabolario dei tag.

Un esempio di XML






La prima linea di codice e’ una dichiarazione XML. Questa indica la versione dell’XML che si sta utilizzando e la codifica di carattere del documento. Tutto quello che segue deve essere contenuto in tags. Ciascun set di tag denota un elemento del documento. Il nome di un elemento e’ contenuto nel tag di apertura e in quello di chiusura. Il valore di un elemento e’ contenuto nel testo tra il tag di apertura e quello di chiusura. E’ importante notare come l’ XML non fa nulla. Il linguaggio fu creato solo come modalita’ di immagazzinamento dati, non per manipolarli. In quest’ottica per manipolare i dati contenuti occorre un linguaggio di programmazione, come il JavaScript, per estrarre le varie informazioni dal file XML e porli nella pagina web.



L’XML in azione


Se avessimo una pagina web con l’elenco dei dipendenti in un ufficio, memorizzato in un file XML, dobbiamo poter recuperare i vari dati dei dipendenti leggendo il file XML, facendo il parsing dei vari tag e gererando gl iopportuni tag HTML per visualizzare questi dati nella pagina web finale, presumibilmente all’interno di qualche contenitore identificato da uno o piu’ layer





I dati di ritorno, richiamati dal nostro componente XHR, verranno gestiti da un codice javascript simile a questo sull’evento onreadystatechange:



Questi dati in formato XML possono essere “percorsi” usando gli stessi metodi forniti dal Document Object Model utilizzati per “navigare” all’interno di un documento HTML.
e si conosce la struttura dell’ XML ricevuto dal server si puo’ recuperare l’informazione desiderata usando i metodi getElementsByTagName e le proprieta’ come nodeValue.

Estrazione dei dati dall’ XML

Sapendo che nel nostro documento XML e’ presente un elemento , si recupera una collezione dei vari elementi con


Sapendo che di tali elementi ce n’e’ uno solo, sono interessato solo al primo elemento di questa collezione:







Questo elemento contiene quindi il nodo desiderato. Il nodo e’ il primo elemento figlio di questo elemento:






Adesso posso prendere il valore di questo nodo testuale usando la sua proprieta’:





ed assegnamo il valore alla variabile javascript:





In questo modo possiamo recuperare anche le informazioni relative al website e alla email:





Usando I metodi del DOM come createElement, createTextNode e appendChild, possiamo ricostruire una porzione di HTML per contenere le informazioni estratte prima:








A questo punto devo inserirei nuovi markup all’interno del layer nel documento:



var details = document.getElementById("details");






Innanzitutto devo assicurarmi che il contenitore sia vuoto, senno’ svuotarlo:



while(details.hasChildNodes()){
details.removeChild(detaild.lastChild); }



poi inserisco il contenuto:



details.appendChild(header);
details.appendChild(link);



Vantaggi dell’ XML

E’ un formato molto versatile per i dati. Si puo’ definire il proprio vocabolario di tag personalizzandolo per i nostri dati. Questa flessibilita’ ha favorito la larga diffusione del formato XML, che nel tempo e’ diventato uno dei modi piu’ usati per scambiare dati nelle applicazioni web. Inoltre per fare il parsing vero e proprio riutilizziamo i metodi propri del nostro Document Object Model senza la necessita’ di usare un altro linguaggio oltre al Javascript.

Svantaggi dell’ XML



Occorre smpre usare il corretto header. E’ necessario che ad ogni tag di apertura corrisponda il suo tag di chiusura con il corretto annidamento degli elementi. E’ quindi facilecommettere un errore.
Utilizzare il DOM per distribuire il contenuto parserizzato puo’ essere una operazione non cosi’ breve per cui sono necessarie molte istruzioni.Ogni nodo deve essere creato ad attaccato al documento. Uno ad uno. Quindi per una applicazione con un file XML grande il codice puo’ diventare presto troppo complesso da gestire con facilita’. Si potrebbero usare a questo proposito le XSLT, o eXtensible Stylesheet Language Transformations, che effettuano un mapping tra XML ed XHTML.
Il problema e’ che non tutti i browser supportano questa funzione avanzata.



Il formato JSON

Abbiamo detto in precedenza che per formattare i dati richiesti al web server possiamo utilizzare un documento html statico o dinamico, oppure un documento xml, o recuperare i dati richiesti secondo il formato JavaScript Object Notation.

In molti ritengono che il formato XML sia il miglior formato per l’interscambio di dati. Come visto prima e’ un formato testuale per cui si puo’ assicurare l’interazione tra sistemi diversi attraverso la difinizione dei DTDs oppure degli Schemi XML. Questi sono dei meccanismi usati comunemente quando si devono trasmettere dati tra sistemi disomogenei o tra piattaforme diverse.

In questo modo si rende il formato dei dati indipendente dalle tecnologie utilizzate per il loro trattamento. Il prezzo da pagare e’ la necessita’ di recuerare dall’XML la strutturazione gerarchica interna a questi dati nel linguaggio proprio dei vari sistemi da cui devono essere elaborati , ed eventualmente ritrasformare i nuovi dati risultanti qualora debbano essere trasmessi ad altri sistemi.

Nel nostro caso dovremo convertire i dati ricevuti in formato XML in oggetti JavaScript.

Quando usiamo il formato diretto html, in abbinamento al metodo innerHTML, questa conversione avviene attraverso il parsing del codice effettuato dal browser e la conseguente creazione degli oggetti JavaScript all’interno del Document Object Model.

Utilizzando l’ XML dobbiamo effettuare esplicitamente il parsing del codice e la distribuzione nel DOM attraverso la valorizzazione degli attrbuti dei nodi interessati oppure la creazione di nuovi Nodi collegati a nodi preesistenti. Cio’ avviene utilizzando i metodi di trattamento forniti dal DOM stesso.

Personalmente non ho mai, se non in casi assolutamente necessari, utilizzato questa impostazione per trattare i dati ricevuti. Ritengo che porti a dover scrivere codice javascript troppo lungo - cosa di per se’ poco efficiente per un linguaggio interpretato come il javascript - e nemmeno tanto intuitivo per le strutture da utilizzare in questo caso specifico (navigazione della gerarchia del DOM, Xpath, espressioni regolari).

Da questo punto di vista la situazione ottimale sarebbe quella di avere a disposizione i dati in un formato che possa essre utilizzato direttamente dal JavaScript, html preformattato a parte.

Questo formato e’ chiamato JSON (http://json.org/) e consiste in un dataset in notazione letterale ad oggetti javascript.


Proviamo a convertire un dataset XML in JSON:








Convertito in notazione JSON diventa:





Il benieficio di questo formato e’ che e’ gia’ in un formato che JavaScript puo’ comprendere, e tutto cio’ che serve fare e’ convertire questo codice in oggetti da mostrare usando il metodo eval() alla stringa:


var data = eval( '(' + x.responseText + ')' );


Cio’ restituisce il contenuto come oggetti che possiamo manipolare attraverso l’uso della notazione array-associativa o di proprieta’ degli oggetti.





Per i fornitori dati nel nostro server l’utilizzo del formato JSON al posto del formato XML e’ decisamente piu’ efficiente e veloce (nei miei test si ha una velocizzazione fino a dieci volte). Comunque dobbiamo stare attenti ad una cosa: l’utilizzo del metodo eval() puo’ essere pericoloso perche’ esso esegue qualsiasi codice javascript, e non solo steinghe JSON. Possiamo aggirare questo problema utilizzando , al posto del metodo direttamente, una funzione di parsing che ci assicuri che solo i dati vengano convertiti in oggetti, mentre il codice potenzialmente pericoloso non venga eseguito.

Esiste una libreria open-source liberamente scaricabile all’indirizzo
http://www.json.org/js.html che contiene il parser per i dati JSON. Nella nostra web application sara’ sufficiente in cludere tale libreria nella pagina principale, insieme all’ajax engine.






Vantaggi del formato JSON


La notazione JSON e’ leggera. Mentre ogni valore in XML richiede un tag di apertura ed uno di chiusura, JSON richiede solo un nome da scrivere una volta sola.
Diversamente dall’ XML, JSON non ha bisogno di essere trasmesso dal web server con uno specifico header “content-type” ma viene trasmesso come testo semplice.


Svantaggi del formato JSON


La sintassi richiesta dal format JSON e’ molto precisa. Un apice al posto sbagliato o una parentesi mancante possono cambiare significato a tutta la stringa JSON. Occorre anche gestire con le sequenze di escape i caratteri speciali come i singoli e i doppi apici. Una stringa JSON complessa puo’ diventare assai poco leggibile a differenza di un dataset XML la cui lettura e’ agevolata dalla presenza dei tag iniziali e finali. In piu’ occorre fare la valutazione della stringa JSON in modo sicuro occorre ricordarsi di processarla con la funzione di parsing opportuna che esegue solo le proprieta’ contenute nella stringa ignorando qualsiasi funzione o metodo in essa presente.


Riassunto


In questo capitolo abbiamo visto alcuni aspetti collegati all’utilizzo del nostro ajax engine all’interno di una web application. Innanzitutto abbiamo visto l’approccio che, a fonte di una pagina html che agisce da puro contenitore, utilizza chiamate multiple ai fornitori (di dati e struttura grafica) per costruire sia l’interfaccia grafica (utilizzando fornitori HTML statici oppure dinamici), sia per popolarne gli elementi.
Poi abbiamo visto come accorpare la costruzione della GUI in un'unica chiamata remota - o in poche chiamate al server, delegando poi ai fornitori dati veri e propri il compito di popolare gli elementi costruiti. In seguito abbiamo visto come utilizzare il formato XML oppure il formato JSON per caricare e distribuire sul client i dati richiesti al server.

lunedì 12 novembre 2007

Tutorial Ajax - Capitolo 2

Come abbiamo visto nel capitolo precedente, il cuore della tecnologia Ajax e’ il componente XMLHttpRequest, per il quale abbiamo visto un paio di tecniche di caricamento in memoria.
Abbiamo anche mostrato quali metodi ed attributi vengono forniti con esso, e introdotto il concetto di transazione asincrona tra browser e web server utilizzando il protocollo http.

A quest punto lasciatemi fare un una piccola analogia.

Abbiamo ora a disposizione una bella ruota, non resta che costruirci attorno un’ automobile. Dapprima vedremo come costruire una utilitaria, ovvero come circondare il componente asincrono con un motore semplificato che possa gestire le operazioni basilari che vogliamo implementare sulla nostra web application (l’Ajax Engine). Successivamente raffineremo l’Ajax Engine e lo completeremo con un modulo di interfacciamento con l’Application Server ed aggiungeremo altre librerie di supporto alla GUI per arrivare ad avere una bella macchina sportiva, attraente come aspetto e valida dal punto di vista prestazionale.


AjaxCore – L’Ajax Engine di base.

Una volta scritta la funzione loadXHR() , bisogna definire il set di funzioni che si occupano del vero e proprio caricamento asincrono dei dati utilizzando il metodo GET oppure POST messi a disposizione, a seconda che si richiedano dei dati al server oppure si voglia anche trasferire un set di parametri preliminari contestalmente alla richiesta. Di solito si omette di utilizzare il metodo PUT.

Quindi il nostro Ajax Engine potra’ contenere le due funzioni seguenti:





Queste due funzioni si occupano della richiesta di una pagina page - statica o dinamica - al web server, definendo un contenitore di destinazione dest dove poi dovremo smistare il risultato ottenuto eventualmente dall’esecuzione di questa pagina sul server , accompagnando la richiesta con un set di parametri pars per costruire la querystring completa da inviare nel caso di utilizzo del metodo POST.

Vediamo un po’ piu’ nel dettaglio il comportamento delle due funzioni.


loadHTMLDoc: dopo aver caricato, se occorre, l’oggetto HDR si crea l’”event handler” collegato all’evento onreadystatechange . Un event handler non e’ altro che l’operazione che deve essere eseguita ogni qualvolta il browser attiva questo evento (event fired) segnalando la variazione di stato dell’oggetto HDR.

Se quindi lo stato dell’oggetto HDR e’ cambiato si controlla quale e’ lo stato attuale, e nel piu’ semplice dei casi si prosegue solo quando (x.readyState == 4 && x.status == 200) , ovvero quando lo stato indica che si e’ ricevuta una risposta dal webserver, e tale risposta ha codice 200 – OK.

In questo caso si associa l’eventuale risposta (responseText o responseXML) all’elemento del Document Object Model passato come contenitore di destinazione per i dati richiesti.


ResponseText, responseXML e DOM

Una volta ricevuti i dati richiesti in modo asincrono al web server, come si “inglobano” nella pagina HTML correntemente visualizzata sul browser? In che formato devono essere trasmessi i dati dal web server?

Per rispondere a queste domande, e soprattutto per capire le scelte fatte nel nostro framework Ajax, occorre considerare il seguente aspetto: come si visualizza una pagina web sul browser?

Generalmente il browser legge il codice sorgente HTML della nostra pagina web inviatogli dal web server. Ne effettua il parsing e interpreta i tag html per formattare il documento e visualizzarlo all’interno della finestra del browser. Durante l’operazione di parsing viene costruita in memoria una struttura ad albero di quella che e’ la struttura interna al documento – il Document Object Model o DOM.

Il DOM non e’ altro quindi che la rappresentazione nella memoria della macchina client della struttura del documento visualizzato dal nostro browser.


Document Object Model (DOM) è una forma di rappresentazione dei documenti strutturati come modello orientato agli oggetti. DOM è lo standard ufficiale del
W3C per la rappresentazione di documenti strutturati in maniera da essere neutrali sia per la lingua che per la piattaforma. DOM è inoltre la base per una vasta gamma delle interfacce di programmazione delle applicazioni; alcune di esse sono standardizzate dal W3C.
DOM è stato inizialmente supportato dai
browser per modificare gli elementi in un documento HTML. DOM è stato un modo per accedere e aggiornare dinamicamente il contenuto, struttura e stile dei documenti. A causa delle incompatibilità nell'esecuzione di DOM fra i vari browser, il W3C ha fornito delle specifiche standard.DOM non mette limitazioni sulla struttura dei dati del documento. Con DOM, un documento ben formato può essere visto come un albero. La maggior parte dei parser XML (come Xerces) e i processori XSL (per esempio Xalan) sono stati sviluppati per usare la struttura ad albero. Questa implementazione richiede che l'intero contenuto di un documento venga analizzato e salvato in memoria. Quindi, DOM può essere usato molto bene per applicazioni dove gli elementi del documento devono essere trovati in modo random e modificati. Per le applicazioni basate su XML che usano un processo di lettura e scrittura per analisi, DOM presenta un grande spreco di memoria; per questo tipo di applicazioni si consiglia di usare il modello SAX.



Questo Document Object Model e’ accessibile al programmatore come struttura XML. A grandi linee l’albero del Document Object Model e’ composto da elementi chiamati Nodi.

· I Nodi identificano i vari elementi, o contenitori, della pagina html .
· I dati veri e propri della pagina, ovvero il contenuto degli elementi html sono rappresentati come attributi dei vari nodi.

Per modificare dinamicamente il contenuto di una pagina web occorre sostanzialmente identificare all’interno dell’albero del DOM il nodo o i nodi che contengono i dati che si vogliono modificare e “appiccicare” il nuovo contenuto al nodo preso come riferimento (parent node), togliendo eventualmente anche i sottonodi (child nodes) con i dati precedenti.

Ad esempio se vogliamo modificare il contenuto di una cella che costituisce una tabella html, occorre modificare il testo racchiuso nei tag … .
Bisogna cioe’ recuperare un riferimento o “reference” della cella/nodo in questione, e cambiare il contenuto interno, sovrascrivendo quello precedente.

Il modo piu’ semplice per sostituire il contenuto della cella in modo dinamico e’ quello di definire il nuovo contenuto valorizzando l’attributo innerHTML del nodo interessato.

Non appena il comando viene interpretato dal browser si ha il refresh automatico di quanto si sta visualizzando sullo schermo, e viene mostrato il nuovo contenuto della cella modificata all’interno della tabella visualizzata nella nostra pagina html caricata, senza doverla ricaricare da zero.

Nel caso di modifiche piu’ complesse si puo’ definire direttamente la struttura del codice html che deve diventare il nuovo valore dell’attributo innerHTML del nodo di riferimento, oppure si puo’ costruire direttamente la struttura XML dei nuovi nodi che devono far parte del DOM modificato.

La prima strada presuppone che il nuovo dato ci venga fornito nativamente come codice html preformattato, mentre la seconda strada lascia una liberta’ maggiore sul formato che devono avere i nuovi dati nel caso vengano forniti da terze parti, magari recuperandoli in remoto da un database server.

Il vantaggio del primo metodo e’ una semplicita’ intrinseca nell’inserimento dei nuovi dati all’interno del DOM preesistente (si valorizza l’attributo innerHTMLdel nodo padre), il vantaggio del secondo e’ una maggiore liberta’ rispetto a fornitori di dati esterni che possono utilizzare il formato XML o altri formati per l’interscambio dei dati, come il formato JSON.

Nel nostro framework semplificato abbiamo optato per mantenere inizialmente una elevata semplicita’ di integrazione della nuova tecnologia all’interno dell’applicazione. Grazie a cio’ la progettazione dei fornitori dati attivati sul webserver rimane pressoche’ invariata rispetto alla normale progettazione di pagine HTML/JSP/ASP.NET, a meno di piccole variazioni che vedremo piu’ avanti nel dettaglio.

Quindi l’impostazione con cui si opera utilizzando i vari fornitori dati e’ la seguente:

- si individua il punto destinazione all’interno del DOM
- si richiama il fornitore dati sul webserver, solitamente una pagina dinamica, a volte un file html preformattato
- si attiva la funzione loadHTMLDoc o loadHTMLPost a seconda del metodo GET o POST di trasmissione necessaria.

Resta ora da capire come individuare all’interno del Document Object Model il punto di inserimento dei dati restituiti dal web server in modo asincrono.


Referenziazione di uno o piu’ elementi all’interno del Document Object Model


Il linguaggio JavaScript fornisce tre metodi principali per ottenere un reference ad uno o piu’ elementi all’interno del DOM ricostruito in memoria:

- document.getElementById();
- document.getElementsByTagName();
- document.getElementsByName();

Tutti e tre i metodi sono metodi associati all’oggetto document, elemento principale del nostro DOM, che rappresenta la nostra pagina web.


Il primo metodo restituisce un reference ad un elemento singolo identificato dall’attributo html ID=”…” all’interno di un Tag. Tale attributo deve essere unico all’interno di tutto il documento. Se cosi’ non avviene si ottiene un reference non valido.




Il secondo metodo getElementsByTagName(“”) restituisce un array di elementi che hanno il Tag html indicato come parametro (incluso tra doppi apici).



Il terzo metodo getElementsByName e’ l’analogo del secondo, ma punta non agli elementi con un TAG specifico, ma con un attributo HTML NAME=”…” identico. Allo stesso modo del metodo precedente ritorna quindi un array contenente i riferimenti a tutti gli elementi con un dato valore dell’attributo NAME.



Per concludere, molto spesso si utilizza una combinazione di questi tre metodi per recuperare i reference degli oggetti desiderati, raggruppati all’interno del nostro documento sfruttanto gli attributi NAME e i TAG.
Il piu’ delle volte comunque si ha necessita’ di recuperare il reference ad un singolo elemento, per cui nel nostro framework, per ottimizzare le dimensioni del sorgente Javascript, e’ stata implementato un wrapper dedicato:


Passaggio di parametri al Web Server e chiamata di pagine dinamiche lato server.


Resta ora da risolvere un altro punto importante all’interno dell’architettura delle applicazioni web tradizionali: come facciamo a richiamare funzioni remote sul web server per effettuare ad esmpio l’inserimento di dati sul Database che contiene i dati mostrati e modificati sul nostro client?

Da quanto analizzato in precedenza si deve utilizzare una variante della funzione loadHTMLPost, per poter passare tutti i parametri col metodo POST. Nel nostro framework aggiungeremo una funzione getBeanResult ed un wrapper setValToDB.

Innanzitutto si e’ scelto di differenziare il metodo base loadHTMLPost per fornirgli maggiori potenzialita’, includendo anche un parametro con cui indicare diversi metodi alternativi nel caso in cui dovessimo trattare in maniera diversa i dati restituiti dal server. Il wrapper serve per semplificare la chiamata del metodo sottostante ottimizzandone le dimensioni del codice.

Stiamo ipotizzando di dover attivare un file getBean.jsp, che utilizza le Java Server Pages per poter interagire con un DB server remoto tramite una libreria di funzioni richiamabili traite il meccanismo dei JavBeans.






Il wrapper nasce dal fatto che la chiamata diretta al metodo sottostante puo’ essere scomoda da usare a causa della complessita’ di formato nel caso particolare in cui occorra inserire dati sul Database, mentre il wrapper ha un formato decisamente piu’ standard:



In questo modo possiamo richiamare una pagina dinamica scritta in JSP passando tutta una serie di parametri costruendo una querystring opportuna. Il risultato ottenuto, ovvero il codice html generato dall’application server, puo’ servire per modificare un attributo all’interno di un nodo, un nodo completo o un insieme di nodi all’interno del nostro Document Object Model.


Come si attiva l’Ajax Engine


Una volta capito come richiedere i dati al web server e come smistarli all’interno della nostra pagina all’interno del browser, ci resta da comprendere come integrare il nostro Ajax Engine semplificato scritto in Javascript all’interno della nostra applicazione.

L’applicazione di codice Javascript ad una pagina web e’ una operazione molto semplice; tutto cio’ che occorre e’ usare il tag seguente:


<#script type="text/javascript">
// codice vero e proprio dello script

<#/script>

Per i browser piu’ datati, oppure se vogliamo utilizzare lo XHTML (la nuova versione dell’html) al posto di quello solito, abbiamo bisogno di commentare il codice per avere la sicurezza che il browser non lo mostri all’interno della pagina o cerchi di interpretarlo come tag html.


Esistono die diversi stili per commentare il codice. Per i documenti html e per quelli xhtml in stile “transitional” si usano i normali commenti html:

<# script type="text/javascript">
<#!--
// codice vero e proprio dello script
--#>

< #/ script>

Per I documenti scritti usando l’ xhtml secondo lo stile “strict” occorre usare la sintassi di commento CDATA. percio’ solitamente in questa tipologia di documenti si preferisce utilizzare codice Javascript solo all’interno di file di scripting a parte.
In questo caso si inserisce all’interno della sezione ... della pagina web il riferimento al file esterno.


Resta da capire, una volta che sappiamo come caricare il file esterno con il nostro script, come far interagire lo script con la pagina web, ovvero in che modo attivarlo.
Finora, nel web 1.0, ci sara’ capitato di scrivere codice javascript in relazione al metodo submit() di un form. In quel caso l’azione scatenata dal metodo richiamato dal form richiamava le funzioni javascript che eventualmente avevamo scritto per gestire la validazione dei dati interni al form, oppure per effettuare una prima fase di trasformazione dei dati stessi prima di inviarli al wb server.

Per attivare il nostro Ajax Engine sfrutteremo il seguente meccanismo implementato nel nostro browser per segnalare l’avvenuto caricamento iniziale della nostra pagina web. Il browser riceve dal web server il codice html della nostra pagina; costruisce in memoria il suo DOM a mano a mano che effettua il parsing dell’html, carica in memoria anche gli evetuali fogli di stile esterni, ed il nostro ajax engine.

Quando questa serie di operazioni termina, prima di effettuare il rendering della pagina, ovvero la visualizzazione del contenuto sul pannello principale del browser, viene lanciato un avviso di avvenuto caricamento, intercettabile tramite un event handler Javascript collegato all’evento onLoad().

Oppure possiamo anche sfruttare una caratteristica propria del caricamento del file javascript esterno. Il codice in esso contenuto viene caricato nella memoria del browser ed immediatamente parserizzato e caricato in memoria se si tratta di variabili o funzioni oppure eseguito se si tratta di una invocazione ad una funzione.

Il primo approccio subordina l’esecuzione del codice javascript ad un evento specificamente conseguente al caricamento della nostra pagina web, mentre il secondo presuppone l’esecuzione del codice non appena il browser ha questa possibilita’. Puo’ anche darsi prima dell’attivazione dell’evento onLoad(). Sinceramente penso dipenda dai meccanismi interni ai vari browser. se vi interessa potrete verificare sulla documentazione rilasciata con i vari browser per vedere quale meccanismo usino.

Il punto importante secondo me e’ che se siamo costretti a subordinare l’esecuzione del nostro codice javascript solo dopo il caricamento di tutti gli elementi della nostra pagina dobbiamo utilizzare la prima tecnica. La seconda e’ utile in tutti gli altri casi, non avendo il vincolo di attivare quell’event handler. All’inizio consiglio l’approccio piu’ prudente, utilizzando l’evento onLoad(), anche per evitare noiosissimi problemi di sincronizzazione tra codice javascript e pagina web, assai ostici da individuare e risolvere.


Attenzione alla Cache

Normalmente la cache del nostro browser ci torna utile. Il browser memorizza i file caricati, cioe’ l’utente non deve caricare ogni volta gli script. Pero’ nell’ approccio Ajax questa tecnica di caching puo’ causare dei problemi.

Il browser Safari e’ quello piu’ pericoloso per noi, perche’ almeno nelle versioni precedenti memorizzava lo status della risposta ottenuta dal web server e non segnalava piu’ le sue variazioni.
Le ultime versioni di questo browser potrebbero non avere piu’ questo comportamento specifico.

Comunque evitare questi problemi di caching e’ relativamente semplice: prima di chiamare il metodo send() nel componente XMLHttpRequest e’ sufficiente aggiungere una intestazione specifica alla richiesta che stiamo effettuando con quel componente.

Questa intestazione ( o header ) segnala al browser la necessita’ di testare se la data e’ variata rispetto ad una data di riferimento. Basta inizializzare questa data di riferimento su una data passata al momento in cui scriviamo il codice:





Riassunto

Abbiamo visto come progettare una piccola libreria JavaScript che ci permette di effettaure richieste HTTP in modo asincrono direttamente al web server per richiedere dati generati in modo statico oppure con una pagina web dinamica senza dover pero’ ricaricare la pagina correntemente visualizzata sul browser. Abbiamo anche compreso come ridistribuire i dati richiesti e ricevuti all’interno del documento visualizzato e come attivare questa libreria all’interno di un documento html. Il vantaggio che immediatamente ci salta all’occhio e’ dato dal fatto di non dover ricaricare la maggior parte di una pagina web nel caso avessimo bisogno di aggiornare solo piccole porzioni se non un singolo dato visualizzato nella nostra interfaccia grafica sul client. L’aggiornamento di pochi dati generalmente e’ pressoche’ istantaneo, riducendo solitamente a pochi bytes il codice trasmesso dal server al client. Anche per dati piu’ corposi di solito l’utente continua a lavorare con la sua applicazione web senza i tempi morti e lo sfarfallio che avviene sul browser dovuti al ricaricamento della pagina completa che si avevano nelle applicazioni tradizionali.

giovedì 8 novembre 2007

Thin Client o Fat Client?

Il Fat Client


Uno dei problemi che uno sviluppatore di applicazioni web in Ajax deve affrontare quando inizia a progettare una nuova RIA, e' come architettare il sistema affinche' risulti veramente innovativo ed interattivo.


In poche parole il sistema deve rispondere idealmente in modo istantaneo alle richieste dell'utente, avendo dal lato opposto il fatto che le risposte dal server possono essere lente in modo avvertibile per l'utente a causa di overheads di processamento e di trasferimento dal server al client.


Il consiglio e' quindi quello di effettuare chiamate remote solo quando non c'e' modo efficiente di ottenere lo stesso risultato sul browser. All'estremo si potrebbe eseguire tutte le operazioni che non coinvolgono una base dati direttamente sul browser.


Solitamente una RIA e' composta da diversi livelli logici o moduli:


  • L'interfaccia Utente (detta piu' comunemente GUI o Graphical User Interface)

  • Il livello della logica dell'Applicazione o della logica applicativa

  • Il livello della logica di Business

  • Il modulo che si occupa dell'accesso ai dati

  • Il modulo che si occupa della comunicazione esterna al sistema

La GUI e' l'insieme di oggetti che l'utente vede e con cui puo' interagire. La logica applicativa e' quell'insieme di funzioni che regolano il dialogo tra l'utente e il computer, la consequenzialita' delle azioni da compiere, la regolazione del flusso di informazioni verso e dal server. Il livello della logica di Business riguarda la conoscenza del dominio e delle policies dell'owner del sito. Il modulo per l'accesso ai dati riguarda l'interazione con un database. Infine l'ultimo livello riguarda un aspetto comune a molti sistemi aziendali.


Le applicazioni web tradizionali concentrano il codice dell'interfaccia utente nel browser sul client, con un mix di HTML e CSS, con un po' di Javascript utilizzato per eseguire qualche semplice task. Tutto il resto viene gestito sul server web.


Noi pero' in Ajax vogliamo fare di meglio, vogliamo migliorare la suddivisione di questi moduli tra web server e client per ottimizzare la reattivita' della nostra applicazione e minimizzare le latenze che possono esserci.


Se spostiamo l' Application Logic (sicuramente)e anche la Business Logic (forse) sul client si migliora la nostra web application Ajax rispetto ad una tradizionale. Adesso e' il browser che controlla il flusso delle attivita'. Quindi quando un utente compie una qualche azione usando la GUI, e' il browser che prende la decisione su come agire in risposta, e invia una richiesta al server solo se necessario, e per servizi specifici.


Riguardo lo spostamento della Business Logic, assolutamente da evitare nelle applicazioni tradizionali, occorre valutare attentamente i possibili pro e contro a causa di alcuni problemi che potrebbero presentarsi:



  • Spostare una Business logic magari basata su PHP, Java o C# in Javascript puo' essere arduo perche' le API standard sono minime e non si hanno a disposizione molti costrutti dei tipici linguaggio che si possono utilizzare lato server.

  • Ci puo' essere un problema di portabilita' dovendo aderire agli standard diversi che ogni browser implementa. Un aiuto a cio' puo' essere dato dall'utilizzo di un framework Javascript.

  • Lo sviluppo di moduli Javascript complessi non ha ancora a disposizione il supporto di un buon ambente integrato di sviluppo come avviene lato server. Percio' si introduce un livello di difficolta' aggiuntiva per lo sviluppatore inesperto.

  • Il codice Javascript puo' essere visionato liberamente rivelando la Business Logic sottostante, a meno di attuare strategie opportune di offuscamento del codice.

  • I dati web non vengono generalmente salvati sul client. Percio' e' comunque necessario avere una parte della business logic sul server in connessione con il modulo dell'accesso al database.

Raccontata cosi' sembra una catastrofe. Per fortuna si possono risolvere questi problemi nei modi seguenti:



  • Javascript si rivela essere un linguaggio molto potente, scoprendo che nelle applicazioni web tradizionali e' stato sostanzialmente sottoutilizzato. Se poi si utilizza un framework dedicato lo sviluppo in javascript diventa molto piu' semplice e puo' dispiegare appieno tutte le sue potenzialita' finora inespresse.

  • Il problema dei diversi browser viene ovviato usando un framework che incapsula e nasconde le varie differenze allo sviluppatore finale.

  • Ci sono librerie che forniscono molti ambienti di Logging, Debugging, DOM Inspection e Traffic Sniffing che semplificano lo sviluppo dell'applicazione javascript e la sua manutenzione.

Di sicuro la programmazione in Javascript non e' piu' "produttiva" rispetto all'utilizzo di un linguaggio lato server. I benefici che si ottengono pero' dallo spostamento dei moduli sul client possono portare a spostare anche la Business Logic oltre che l'Application Logic.


Occorre ancora ribadire che Javascript "gira" piu' lentamente delle equivalenti applicazioni desktop, cosi' che l'ottimizzazione e' molto importante. Occorre anche tenere presente l'utilizzo della memoria di sistema ed evitare i bachi specifici di ogni browser che possono portare a sprechi e inefficienze nella memoria utilizzata.


Alternative al Fat Client


Il Thin Client


Un client leggero contiene solo il codice Javascript basilare ed effettua frequenti richieste al server conseguenti all'interazione con l'utente. Questo approccio e' utile quando:


  • La business logic richiede tecniche e librerie complesse che possono essere implementate solo lato server

  • Ci sono degli impedimenti sullo spostamento verso il client dell' Application e della Business Logic

Il Desktop Client


E' sostanzialmente l'approccio tradizionale della creazione di applicazioni che vengono eseguite sul client direttamente, che hanno bisogno di una installazione preventiva e che si appoggiano direttamente al sistema operativo della macchina dell'utente.


Solitamente la connessione con un database server viene effettuata usando un connettore al database server o attraverso connessioni che si appoggiano su un socket di rete dedicato verso una parte server dell'applicazione.

martedì 6 novembre 2007

Tutorial Ajax - Capitolo 1

Capitolo 1 - La “Tecnologia” AJAX

Introduzione

Fino all’avvento della tecnologia AJAX, l’interazione tra client e server veniva effettuata in modo sincrono.

I dati presenti in un FORM venivano inviati tramite la funzione SUBMIT al web server, specificando con il metodo GET oppure POST la modalita’ con cui veniva effettuata la transazione e la trasmissione delle variabili – in chiaro oppure no – richiedendo l’esecuzione di una azione specifica da parte dell’application server in risposta a questa richiesta.

Solitamente si tratta dell’apertura di una pagina dinamica lato server (scritta di solito in JSP, PHP,o ASP) che si occupa del trattamento dei dati inviati, presenti nel form.

Questa pagina eventualmente effettua delle interazioni con un database server, e infine si occupa della creazione dell’output successivo che viene inviato dal webserver al browser dell’utente che aveva attivato l’operazione iniziale di Submit.

Successivamente il browser deve effettuare di nuovo il parsing – ovvero l’interpretazione del codice html e javascript ricevuto - , la costruzione del Document Object Model (DOM) in memoria e la visualizzazione della nuova pagina web come risultato finale di tutte queste operazioni.

Probabilmente non ci siamo nemmeno tanto preoccupati della fase di creazione del modello ad oggetti di rappresentazione della pagina che vogliamo visualizzare dentro il nostro browser, quello che viene detto Document Object Model, poiche’ raramente avremo avuto necessita’ di intervenire su di esso una volta creato.

Facciamo ora qualche considerazione su questo flusso di operazioni, puntando la nostra attenzione sull’efficienza complessiva.
Tutto il processo appena descritto – anche se per sommi capi - implica i seguenti punti critici di inefficienza:

- Nel caso di POST tutti gli stati attuali degli oggetti interni alla pagina contenente il form vengono inviati verso il web server remoto.
- il web server deve inviare una nuova pagina completa al browser come risultato delle operazioni di trattamento dei dati inviati.
- la pagina visualizzata sul browser viene “distrutta” quando si riceve la nuova pagina di risposta, e si ha di conseguenza la perdita dello stato di tutti gli oggetti che compongono la vecchia pagina nella memoria del browser, e la ricostruzione integrale del Document Object Model della nuova pagina da visualizzare.


Se abbiamo a che fare con il caricamento di una pagina totalmente diversa dalla precedente tutto cio’ e’ pressoche’ inevitabile.

E come vedremo sara’ cosi’ anche in Ajax.

Pero’ nel caso in cui viene modificato un unico dato di un form con diverse decine di elementi e dobbiamo ricaricare la stessa pagina aggiornata come conseguenza delle informazioni appena inserite, tipo il nostro esempio del CAP di una citta’ , tutta la pagina deve essere ricaricata completamente dal web server, perdipiu’ in modo sincrono.

Che significa in modo sincrono? Che l’utente non puo’ effettuare nessuna operazione sul form fintantoche’ non viene caricata la nuova versione aggiornata.

Per cui se il canale trasmissivo e’ congestionato, oppure stretto, o asimmetrico tra browser e web server, l’utente deve rimanere in attesa anche qualche secondo per poter continuare ad utilizzare il form in questione.

Se si trattasse di una applicazione desktop ci sarebbe gia’ un capannello di utenti pronti a farci la pelle se ci fossero questi tempo morti tra operazioni successive sullo stesso form!!!

Oltre a cio’ lo sviluppatore deve scontrarsi con il problema che le applicazioni web non riescono a mantenere lo stato degli oggetti interni come abbiamo visto prima.

Questo insieme di inefficienze era un aspetto imprescindibile nella costruzione delle interfacce grafiche “stateless” che hanno caratterizzato le applicazioni web fin dall’origine – per cui si parla comunemente di prima generazione di web applications, o Web 1.0.

Nel frattempo era avvenuta una innovazione che, come capita spesso con le innovazioni, non riscosse il meritato interesse.

Nel 2000 Microsoft sviluppa Outlook Web Access – OWA - , un prodotto per fornire una interfaccia web per il proprio Mail Server Outlook; OWA al suo interno contiene il componente ActiveX “XMLHTTP”.

Originariamente questo componente e’ stato scritto dal team di sviluppo di OWA, e successivamente venne incluso in Internet Explorer 5.0 e reso accessibile sul browser tramite vari linguaggi di scripting supportati da IE, tra cui Javascript, JScript e VBScript.
Il progetto Mozilla successivamente incorpora la prima implementazione nativa compatibile dell’oggetto XMLHttpRequest nel browser Mozilla 1.0 nel 2002. Successivamente seguita dalle implementazioni native nei browser Safari, Konqueror, Opera, Firefox e iCab.

Quindi vediamo che l’oggetto che sta alla base della nuova filosofia AJAX e’ presente in tutti i browser da molti anni. Questo componente permette agli script eseguiti sul browser di effettuare richieste HTTP in modo diretto senza passare dalla funzione Submit interna ad un form.

Nessuno pero’ aveva colto le potenzialita’ progettuali offerte da questo componente disponibile su tutti i browser. La ruota era stata inventata; restava da capire a cosa potesse servire e come poterla utilizzare!

Ma solo nel 2005, grazie ad un articolo di Jesse James Garrett – Ajax: A New Approach to Web Applications (
http://www.adaptivepath.com/publications/essays/archives/000385.php) si comincia a parlare di un nuovo approccio di progettazione delle web applications che fa uso di tecnologie esistenti, comunemente utilizzate, e che non richiedono l’aggiunta di plugin o componenti esterni aggiuntivi ai browser utilizzati.

La tecnica Ajax utilizza una combinazione di:

- HTML(o XHTML) e CSS (Cascading Style Sheets) per il markup e lo stile;

- DOM (Document Object Model) manipolato attraverso un linguaggio ECMAScript come JavaScript o JScript per mostrare le informazioni ed interagirvi;


- l'oggetto XMLHttpRequest per l'interscambio asincrono dei dati tra il browswer dell'utente e il web server. In alcuni framework Ajax e in certe situazioni, può essere usato un oggetto IFrame invece di XMLHttpRequest per scambiare i dati con il server e, in altre implementazioni, tag "script" aggiunti dinamicamente (JSON – Javascript Object Notation);

- in genere viene usato XML come formato di scambio dei dati, anche se di fatto qualunque formato può essere utilizzato, incluso testo semplice, HTML preformattato, JSON e perfino EBML. Questi file sono solitamente generati dinamicamente da script lato server.

Come il DHTML (o LAMP), Ajax non è una nuova tecnologia individuale, piuttosto è un gruppo di tecnologie utilizzate insieme.

Tutti I browser odierni possono utilizzare l’oggetto “XMLHttpRequest” che permette di effettuare richieste di carattere asincrono tra browser e webserver.

Mozilla Firefox ha questo componente direttamente disponibile – embedded nel codice del browser, mentre per Internet Explorer occorre caricare esplicitamente il componente ActiveX esterno “Microsoft.XMLHTTP”.

Come si fa a caricare il componente ActiveX XMLHTTP esterno?


Il codice Javascript seguente serve per il caricamento del componente activeX puo’ essere simile a questo:





Questo semplice codice associa alla variabile loadXHR il riferimento ad una funzione anonima che istanzia un oggetto HDR e vi associa il componente ActiveX Microsoft.XMLHTTP oppure l’oggetto nativo XMLHttpRequest( ) a seconda del browser (IE oppure Mozilla).

Internet Explorer, fino alla versione 6, non possiede l’oggetto nativo XMLHttpRequest, mentre Mozilla-Firefox e gli altri browsers non riescono a caricare gli oggetti ActiveX.

Per cui testando il caricamento degli oggetti ActiveX riusciamo a discriminare IE6 dagli altri browsers.

Se con IE non riesce a caricare il componente standard, si tenta di caricare una libreria alternativa – Msxml2. Se non riesce a caricare nemmeno questa seconda ritorna al chiamante un oggetto referenziato in modo “undefined”. Se invece abbiamo a che fare con un altro browser allora caricheremo, se disponibile, l’oggetto XMLHttpRequest nativo.


Dall’ ultima versione di Internet Explorer, la versione 7, si e’ reso nativo il componente, equiparando il tutto al caricamento dell’oggetto XMLHttpRequest.




In questo caso proviamo innanzitutto a caricare il componente nativo. Se cio’ non ha esito positivo (entriamo cioe’ nel ramo “catch”), probabilmente ci troviamo in un browser IE6 o precedente; percio’ tentiamo dapprima di caricare il componente ActiveX alternativo, che si suppone sia quello avanzato piu’ recente; se anche questo secondo tentativo non va a buon fine cerchiamo di caricare il componente primitivo come ultima possibilita’.


Dobbiamo vedere adesso quali funzionalita’ sono offerte dal componente appena caricato.

Prenderemo in esame il componente nativo, dato che quello piu’ datato e specifico per IE6- offre le stesse funzionalita’ differenziandosi solamente nel numero di stati collegati all’attributo readyState.

L’Oggetto XMLHttpRequest - XMLHTTP

Sia che si utilizzi l’oggetto nativo XMLHttpRequest che il controllo ActiveX Microsoft.XMLHTTP, si hanno a disposizione I seguenti metodi e i seguenti attributi:










MetodoDescrizione
abort() Cancella la richiesta in atto.
getAllResponseHeaders()Restituisce sotto forma di stringa tutti gli header HTTP
ricevuti dal server
getResponseHeader( nome_header ) Restituisce il valore dell'header HTTP specificato
open(metodo,URL )open(metodo,URL,async )open(metodo,URL,async,userName )open(metodo,URL,async,userName,password)Specifica il metodo, l'URL, and altri parametri opzionali
per la richiesta.
Il parametro metodo può assumere valore di
"GET", "POST", oppure "PUT" ("GET" è
utilizzato quando si richiedono dati, mentre "POST" è utilizzato
per inviare dati, specialmente se la lunghezza dei dati da trasmettere è
maggiore di 512 bytes).
Il parametro URL può essere sia relativo
che assoluto.
Il parametro "async" specifica se
la richiesta deve essere gestita in modo asincrono oppure no –
"true" significa che lo script può proseguire l'elaborazione senza
aspettare la risposta dopo il metodo send(), mentre "false"
significa che lo script è costretto ad aspettare una risposta dal server
prima di continuare.
send( content ) Invia la richiesta
setRequestHeader( chiave, valore)Aggiunge la coppia chiave/valore alla richiesta da
inviare.
onreadystatechangeGestore dell'evento lanciato ad ogni cambiamento di stato.
readyStateRestituisce lo stato corrente dell'istanza di XMLHttpRequest: 0 = non inizializzato, 1 = aperto, 2 = richiesta inviata, 3 = risposta in ricezione e 4 = risposta ricevuta.
statusTextRestituisce lo status in forma di stringa descrittiva (per esempio. "Not Found" oppure "OK").
responseTextRestituisce la risposta del server in formato stringa
responseXMLRestituisce la risposta del server come XML, che potrà essere analizzato e parsato come secondo le specifiche DOM del W3C.
statusRestituisce il codice HTTP restituito dal server (per esempio 404 per "Not Found" e 200 per "OK").


Perche’ AJAX?


Se consideriamo il termine nella sua accezione originaria esso e’ l’acronimo di “Asynchronous JAvascript and Xml”, che possiamo tradurre come “(utilizzo di) Javascript ed XML in modo asincrono”.

A come Asincrono


Il termine “asincrono” significa che lo script che utilizza l’oggetto XMLHttpRequest puo’ proseguire nell’elaborazione del codice successivo senza attendere il risultato atteso dopo il metodo send() fino a che sia reso effettivamente disponibile da parte del web server .

Ovvero, per chi conosce il meccanismo degli event handlers in Javascript, si definisce l’event handler associato all’evento onreadystatechange .

Quando l’engine javascript ricevera’ i dati dal web server verra’ richiamato l’event handler , eseguendolo non appena possibile, cioe’ appena terminata l’istruzione corrente che si trovava in esecuzione che probabilmente appartiene ad una diversa porzione del codice dello script, opure immediatamente se l’engine si trova in uno stato di inattivita’.

Per la precisione e’ possibile forzare l’oggetto per renderlo sincrono rispetto al resto dello script. In questo caso si interrompe l’esecuzione delle istruzioni successive al send() finche’ non si riceve la risposta da parte del web server.
Pero’ in questo modo non possiamo continuare ad eseguire altro codice nell’attesa, e se il web server non fornisce una risposta non possiamo riprendere l’esecuzione dello script.

Personalmente preferisco lasciare attivata l’impostazione asincrona, permettendo l’eventuale completamento dello script mentre si attendono i dati richiesti al server.


JA come JAvaScript

Se nel web 1.0 l’utilizzo del linguaggio Javascript era limitato a qualche riga di codice necessario a validare i campi di un form prima di inviare i dati al server, oppure a sviluppare qualche elemento visuale sul client come un menu ad albero (TreeMenu), nel nuovo approccio progettuale Javascript assume il ruolo principale per la creazione di un Engine global del client.

Nella sostanza, non avendo teoricamente piu’ la necessita’ di utilizzare gli oggetti Form e il loro meccanismo di Submit, potremmo non dover piu’ dismettere una pagina web e caricarne una nuova che contenga i dati aggiornati, ma caricare solo e soltanto i dati aggiornati e smistarli nella pagina web attuale.

Vedremo nel dettaglio quanta importanza assumera’ il linguaggio JavaScript nell’ambito della progettazione di una applicazione web Ajax.


- inizializzare la nostra applicazione caricando l’oggetto XMLHttpRequest
- intercettare le azioni effettuate dall’utente tramite l’interfaccia grafica
- identificare gli oggetti visuali coinvolti e gestire i valori associati ad essi
- gestire le condizioni per attivare l’evento send() , costruendo la richiesta che vogliamo effettuare in modo opportuno
- smistare i dati ricevuti in risposta dal serverIl linguaggio Javascript ora ci serve per:



Tutto cio’ e’ accompagnato dall’utilizzo delle strutture - funzioni di libreria ed attributi - rese disponibili all’interno del Document Object Model della pagina web . Percio’ alla base dell’utilizzo del javascript deve esserci una buona conoscenza del DOM creato da parte del browser all’atto del caricamento di una pagina web.



X come XML (eXtensible Markup Language)


Non preoccupatevi, l’utilizzo dell’xml non e’ obbligatorio. Gia’ vi sentivo: “va bene dover utilizzare javascript, un linguaggio ritenuto ostico, ma non anche l’xml...” .

Semplicemente Jesse James Garrett ha preso in considerazione l’xml come formato dei dati da ridistribuire all’interno di una pagina una volta che siano arrivati a fronte di una richiesta asincrona fatta al web server.

In realta’ oltre all’xml si puo’ utilizzare direttamente l’html oppure JSON (javascript Object Notation) come formato dei dati scambiati in modo asincrono. Il formato che preferisco per la flessibilita’ offerta e’ JSON, mentre l’HTML permette la massima velocita’ di ridistribuzione dei dati all’interno della pagina.

Personalmente non utilizzo l’XML, che secondo me comporta la scrittura di piu’ linee di codice e una maggiore lentezza per smistare i dati negli oggetti voluti.

Analizzeremo comunque successivamente le varie tecniche che possono essere utilizzate per formattare i dati scambiati tra client e server in modo asincrono secondo questi tre formati elencati, provando ad elencare pregi e difetti di ognuno secondo la mia personalissima esperienza.






Tutorial Ajax - Introduzione

Premessa

Questo Tutorial e’ indirizzato a programmatori che si trovano gia’ a progettare applicazioni aziendali fruibili attraverso Internet utilizzando un browser per visualizzare l’Interfaccia Grafica – o GUI , Graphical User Interface – che siano gia’ in possesso di una buona conoscenza del linguaggio HTML abbinato alla conoscenza dei Fogli di Stile a Cascata e ai piu’ elementari rudimenti del linguaggio JavaScript .

I CSS o Cascading Style Sheets riguardano gli aspetti progettuali per quanto concerne gli stili da applicare ai documenti html o xhtml, utili per separare i contenuti dalla formattazione. Javascript e’ il linguaggio di scripting maggiormente utilizzato per scrivere codice eseguibile all’interno del browser.

Reputo facoltativa ma caldamente consigliata la conoscenza specifica di un linguaggio per la progettazione di pagine web dinamiche, poiche’ nel corso di questo manuale si introdurranno comunque delle tecniche di programmazione di contenuti dinamici sul webserver/application server utilizzando JSP e ASP.NET+C#.
Ritengo che possa essere ugualmente utile la conoscenza alternativa di uno degli altri linguaggi , PHP, Ruby, VB.NET , ASP 3.0, che oggigiorno e’ possibile utilizzare per creare contenuti dinamici sul web.

Sono anche consigliate le conoscenze basilari riguardo aspetti correlati alla progettazione web quali quelle relative al Document Object Model di un browser, le modalita’ di trasmissione dati attraverso il protocollo HTTP, e la conoscenza dell’architettura di un WebServer quale puo’ essere Apache o IIS, o meglio di un Application Server quale Tomcat (per il JSP) oppure IIS abbinato al Framework .NET (per ASP.NET+C#).

Per chi volesse invece intraprendere da zero l’arte della progettazione di pagine web, statiche e dinamiche, consiglio la lettura preliminare di un manuale introduttivo all’ html/xhtml abbinato ad un manuale di JavaScript e a un tutorial introduttivo per quanto riguarda i CSS.

Se fate parte di un team di progettazione web in cui i ruoli tra gli sviluppatori della parte client e gli sviluppatori della parte server sono separati tra loro, la conoscenza dei linguaggi dinamici e dei meccanismi che sottostanno ad un web/application server non saranno necessari.

Se invece, come me, vi siete sempre occupati di tutti gli aspetti inerenti la progettazione di web applications, non mi rimane che augurarvi buona lettura, con la speranza – ma anche la certezza - di potervi essere utile con questo manuale per scoprire tutte le potenzialita’ che Ajax puo’ offrire per migliorare le web applications che ci troveremo a progettare, per quanto esse possano diventare complesse.

Introduzione

Ormai sono quasi due anni da quando mi sono imbattuto, navigando in rete alla ricerca di articoli e manuali per accrescere il mio background tecnico relativo alla progettazione di applicazioni web, nel termine forse attualmente piu’ alla moda nel panorama della progettazione web – la Tecnologia AJAX.

Parlando di progettazione di applicazioni web mi voglio riferire non ai siti web tradizionali – siti di News , di Informazioni tecniche, che normalmente immaginiamo di incontrare durante la nostra esperienza di navigazione sul web, ma a quelle applicazioni che possono essere distribuite su un browser all’interno di una Intranet Aziendale, come puo’ essere una applicazione per gestire i Fogli Ore dei Dipendenti oppure l’applicazione per la Posta Elettronica , o una applicazione per la gestione delle Commesse Clienti o del Magazzino.

Gli esempi di applicazioni aziendali o di carattere personale possono essere innumerevoli; pensiamo ad esempio alla gestione della propria rubrica telefonica o ad una applicazione per gestire le entrate/uscite familiari.

Tecnologia AJAX – Di quale diavoleria ultra sofisticata stiamo parlando?

Fino a quel momento conoscevo le seguenti tecnologie web per costruire siti “dinamici” : PHP, ASP, JSP, ASP.NET. Le avevo gia’ utilizzate tutte quante negli anni precedenti per progettare piccole applicazioni web aziendali per vari clienti.

Dall’applicazione che gestiva l’anagrafica degli sportelli di un grande Istituto Bancario, al progetto di un portale per la gestone dei Fogli Ore e delle Note Spese dei dipendenti e dei consulenti per una azienda di consulenza informatica. Dal portale per la gestione degli ordini e del catalogo prodotti di una azienda di serramenti al sito web di supporto ad una serie di corsi relativi alla progettazione di siti web dinamici da me tenuti all’interno di una commessa relativa all’erogazione di corsi di tecnologie informatiche.

Sono sempre stato attratto dalle novita’ collegate al mondo della programmazione web, e stavo anche prendendo in considerazione la prospettiva di approfondire le mie conoscenze anche sul framework delle Java Server Faces e di Struts, come pure del linguaggio Ruby e del framework Ruby on Rails. Di queste tecnologie piu’ o meno ne avevo sentito parlare diffusamente ,ma quando mi sono imbattuto in Ajax non immaginavo proprio di cosa si trattasse.

Conoscevo d’altronde, come tutti, le Google Maps (e chi non le conosce, direte voi). E mi ero sempre chiesto quale fosse il trucco grazie al quale i programmatori di Google avessero potuto creare una applicazione web veloce e cosi’ “avanti” rispetto alle applicazioni che si riuscivano a fare normalmente.

Avevo sentito nominare Ajax solo una volta, relativamente ad un’altra applicazione in fase di sviluppo sempre da parte di Google per ricreare un foglio di calcolo Excel-like sul web, pensando tuttavia che potessero fare uso dello stesso “trucco” delle Maps, un qualche plugin proprietario blindato e quindi non utilizzabile nelle applicazioni di tutti i giorni.

Quando mi e’ capitato sottomano il libro “Pragmatic Ajax – A web 2.0 primer – sono stato preso dalla curosita’ di vedere effettivamente in cosa consisteva questa tecnologia che nel frattempo acquisiva sempre maggior fama sui siti tecnici di programmazione web, promettendo la possibilita’ di progettare applicazioni web innovative e rivoluzionarie (appunto si parlava di web 2.0, una nuova era per il web), le cosiddette Rich Internet Applications – o RIA, come capita spesso di leggere sul web.

Da allora e’ passato un po’ di tempo, circa un anno e mezzo, e quello che vorrei fare ora e’ raccontare la mia personalissima esperienza con questa tecnologia, sperando che possa essere di un qualche aiuto per comprenderla almeno un poco, ma soprattutto per farvi capire per quale motivo ha rivoluzionato lo scenario della progettazione delle applicazioni web, come anche la mia esperienza lavorativa .



Il Web 1.0 – Che noia!

Se avete cominciato a progettare pagine web da qualche tempo, il percorso che probabilmente avrete seguito puo’ essere simile al mio:

· si parte imparando un po’ di HTML, si fanno le prime paginette statiche – qualche immagine, qualche link qua e la’, la immancabile immaine/barra “Under Construction” con l’omino che lavora.
· Si aggiungono i contenuti dinamici – la data attuale, pagine variabili a seconda dell’utente collegato
· Si gestisce il collegamento con un database per recuperare dinamicamente i dati da visualizzare e per memorizzare i dati immessi. Si cominciano a progettare i primi form piu’ o meno complessi.
· Si progettano form sempre piu’ complessi su pagine diverse, gestendo le operazioni di “Submit” grazie ad un linguaggio dinamico tra quelli visti prima (PHP, ASP, o JSP) e memorizzando le informazioni comuni a varie pagine tramite le variabili di sessione.
· Si gestisce il mantenimento dello stato all’interno di una stessa pagina sempre grazie alle variabili di sessione, o magari grazie ai meccanismi propri dei JavaBeans nel caso del JSP o grazie ai meccanismi interni del framework .NET nel caso dell’ASP.NET

Non e’ detto che tutti debbano seguire questo percorso. A me e’ capitato piu’ o meno questo; ma quando ho iniziato ad interessarmi alla programmazione web, nel lontano 1995 all’universita’ (in realta’ gia’ nel 1990 si usava internet all’universita’ ma all’epoca il www non esisteva ancora, c’erano pero’ le e-mail, usenet, gopher,l’ FTP, le BBS, le news, e soprattutto IRC tra le varie universita’ di Milano – bei tempi quelli....) esisteva solo l’HTML e le Common Gatweay Interfaces in Perl.

Finche’ si tratta di fare pagine web “classiche”, ovvero in cui c’e’ un testo da visualizzare, con immagini, link, a cui si puo’ applicare una formattazione con i fogli stile basata sui CSS, non ci sono molti problemi, e’ tutto sommato molto elementare, a mio avviso. Procede tutto liscio senza troppi inghippi anche quando si deve progettare un piccolo form per inserire qualche dato in un database, e visualizzare dinamicamente i risultati.

Si utilizza anche qualche linea di codice scritta in Javascript per validare i campi del form direttamente sul client senza dover effettuare una “Submit” e quindi fare la validazione sul server.
Ma fatti una volta o due va tutto bene. La maggior parte del valore aggiunto di un sito web di questo tipo si gioca o sulle caratteristiche grafiche del sito stesso, sulla sua ergonomia.
Diciamo che fatto uno, fatti tutti....personalmente mi annoiavo dopo un po’ quando progettavo siti web di questo tipo. Dopo un po’ non ci trovavo nulla di interessante, di stimolante.

Percio’ poi mi sono dedicato allo sviluppo non tanto di pagine web quanto di applicazioni aziendali distribuite sul web. Pero’ questo tipo di applicazioni non hanno mai avuto un enorme successo per una serie di difficolta’ tecniche e pratiche.




Il problema del Web 1.0 – I Browser sono smemorati!


Il grosso problema che avevo sempre incontrato nella progettazione di web-applications complesse come gestione dell’interazione tra utente ed interfaccia grafica era che il browser, lo user-agent su cui si “eseguono” le pagine stesse, non fosse in grado di mantenere lo stato delle variabili contenute nel codice dinamico nel passaggio da una pagina ad un’altra.

Mi spiego meglio. Supponiamo che nella prima pagina di un form per inserire il i dati anagrafici di un dipendente devo popolare i dati di citta’ e CAP, devo gestire l’inserimento del secondo campo subordinandolo alla scelta del primo. Quindi per caricare l’elenco dei CAP collegati ad una citta’ sono costretto a scegliere tra le due alternative:

- O carico l’elenco completo di tutti i CAP di tutte le citta’ che l’utente puo’ scegliere
- O faccio una submit verso il server della citta’ scelta per caricare i CAP relativi.

Il primo caso e’ poco efficiente, perche’ magari devo caricare un elenco lunghissimo di CAP che non mi servono, e per cui devo trovare anche un modo per “nascondere” i CAP che non corrispondono alla citta’ che l’utente potra’ scegliere.

Nel secondo caso si deve ovviare al problema che quando ricarico la pagina la seconda volta il browser non riesce automaticamente a “ricordarsi” cosa era stato selezionato sul form precedentemente. Ovvero il browser si “dimentica” quale fosse lo stato delle variabili sottostanti collegate ai vari elementi del form di inserimento.

Per questo motivo siamo costretti a mantenere traccia sul server della struttura e del valore di tutte le variabili del nostro form, di modo che l’operazione di submit trasmetta al server i valori attuali che poi il server restituira’ al client quando popolera’ la lista aggiornata dei CAP per la citta’ selezionata.

Questo non e’ nemmeno la situazione peggiore, anzi e’ una di quelle piu’ semplici da gestire.

In fin dei conti si tratta sempre della stessa pagina. Ma se dovessi passare dei valori da una pagina alla successiva o magari rendere disponibili dei valori comuni a tutte le altre pagine, e il loro comportamento dipende dal valore assunto da queste variabili “globali” che magari possono anche andare in conflitto tra loro?

Ecco l’incubo di chi ha progettato web-applications finora.

Dover riempire il codice dinamico da far eseguire all’application server di strutture di controllo, di costrutti “if ...then ...else”, di sezioni html “camaleontiche” per gestire le chiamate successive alla stessa pagina e i cambiamenti di stato delle variabili sottostanti.

Per non parlare dell’uso del Javascript sul client per preparare le variabili da trasmettere al server quando si attivava l’operazione di “submit” di un form.

A parte la difficolta’ tecnica di questo approccio, quello che piu’ mi infastidiva era che trovavo il tutto poco naturale e poco intuitivo da gestire rispetto all’approccio che si usava ad esempio nella progettazione di desktop-applications con un linguaggio event-based come VisualBasic o VisualC++, per non parlare della progettazione delle interfacce grafiche fatte in Java con la libreria SWING o fatte in applicazioni C# desktop usano VisualStudio.NET.

Sinceramente mi sarebbe piaciuto poter utilizzare la stessa impostazione per sviluppare delle applicazioni distribuite che avessero il browser come client, e non un client da installare su ogni postazione e da far girare sul desktop.


Ajax ed il web 2.0


Premetto una cosa: se pensate che quando si parla di Ajax si stia parlando di una vera e propria tecnologia, o se qualcuno ve lo vuol far credere, non e’ cosi’.

Alcuni definiscono Ajax come un nuovo approccio di progettazione, io tendo a considerarla come lo spostamento della visuale del progettista web verso lo stile di progettazione “ad eventi” tanto caro alle desktop-applications.

Chi ha programmato in VisualBasic non deve imparare un nuovo approccio, ma si ritrova a dover utilizzare quello seguito abitualmente.

Per brevita’ usero’ comunque io stesso il termine “tecnologia” associato al terine “Ajax”, intendendo pero’ quanto detto prima.

Prima di cominciare con i dettagli tecnici vorrei aggiungere una cosa soltanto: questo nuovo approccio permette davvero di poter creare applicazioni web innovative, con un elevato valore aggiunto rispetto a quelle che potreste aver sviluppato finora, ma tutto cio’ non “viene via gratis”.

In un certo senso preparatevi a dover imparare quasi da zero a progettare e sviluppare web-applications; quello che vi serve probabilmente lo conoscete gia’: html, javascript, dhtml/DOM, ed un linguaggio di programmazione lato server come php, jsp o asp.net+c#. Bisogna solo imparare ad usarli in modo diverso rispetto a quanto fatto finora.