Questo articolo cerca di dare una risposta alle seguenti domande: che cos‘è AJAX? Cosa vuol dire scrivere applicazioni AJAX? Perchè si dovrebbe conoscere AJAX? Cosa c‘entra Java in tutto questo ?
Viene presentato un semplice esempio per mettere in pratica tutto quello che viene descritto.
Introduzione
AJAX non è l‘ennesima architettura per il mondo web; in realtà è l‘unione di molte tecnologie Open Source già esistenti. Infatti, AJAX è un termine coniato da Jesse James Garrett nel 2005 e sta per Asynchronous Javascript And XML e raggruppa in una sola parola la tecnica per realizzare applicazioni web più dinamiche, più user-friendly e più facilmente fruibili dall‘utente finale.
Vediamo il dettaglio di ciascun termine:
- Asynchronous: è il tipo di colloquio tra client e server.
- Javascript: è il linguaggio che viene utilizzato dal browser sul client all‘interno di una pagina web per poter richiamare il server e valutare la risposta.
- XML: i dati che transitano tra Client e Server possono essere tracciati XML il cui contenuto è composto solo dai dati necessari alla pagina web e tramite gli oggetti Javascript DOM è possibile leggerli e manipolarli.
Oltre a questo, ovviamente, c‘è sempre HTML e CSS per disegnare le pagine web e DHTML per rendere dinamico il contenuto delle medesime.
AJAX è un nuovo modo per sviluppare le applicazioni WEB. Alcuni esempi sono già presenti su internet come ad esempio Writely (http://www.writely.com), Google Maps (http://maps.google.com/), Google Readers, Gmail (http://mail.google.com/mail/), Google Suggest (http://www.google.com/webhp?complete=1), Flickr (http://www.flickr.com/), e così via.
Architettura: modello classico e modello AJAX a confronto
Come rappresentato in Figura 1, le applicazioni web solite funzionano in questo modo: l‘utente effettua una REQUEST verso il server a fronte di una specifica azione (clic su un bottone, su un link, su un‘ immagine, ecc.); il server riceve i dati di una FORM via GET o POST, effettua una elaborazione dei dati e prepara la RESPONSE spedendo al client una nuova pagina web che andrà a sostituire (o a ricaricare) la pagina precedente presente sul browser dell‘utente.
La caratteristica di questa modalità di colloquio è che c‘è sempre qualcuno che deve aspettare: il server aspetta sino a quando un client non effettua una GET/POST e un client aspetta sino a quando il server non ha concluso l‘elaborazione e preparato la pagina HTML di output.
Per ridurre questi tempi di attesa e rendere il client ed il server più interconnessi tra loro, è stato studiato un nuovo modo di scrivere le applicazioni web.
Come mostrato in figura 3, le applicazioni web utilizzano AJAX nel modo seguente: un‘applicazione AJAX elimina questo approccio di inizio e fine comunicazione (REQUEST e RESPONSE) utilizzando invece un motore AJAX che viene richiamato nella pagina web e si preoccupa di dialogare con il server in modo asincrono (o sincrono).
Come illustrato in figura 4, il motore AJAX ha il compito di comunicare in modo asincrono con il server in base a particolari eventi (scrittura in un campo TEXT, selezione di un elemento di una COMBO, ecc.) e deve richiamare le opportune funzioni Javascript che ridisegnano dinamicamente le pagine web. In questo modo, l‘utente non dovrà più attendere che la pagina venga ricaricata ma semplicemente la vedrà cambiare davanti ai sui occhi contestualmente ai dati che sta immettendo nella FORM.
Fino ad ora, nulla è stato detto sulla parte server. Infatti, AJAX è specifico per il Presentation Layer e il server può seguire una qualsiasi tecnologia disponibile: J2EE con linguaggio Java o LAMP con linguaggio PHP oppure .Net con C#. È il motore AJAX che dovrà dialogare con un protocollo standard (XML o SOAP) oppure proprietario (testo, CSV, ecc.) con il server.
In questo articolo, l‘esempio che in seguito verrà illustrato è focalizzato sulla tecnologia J2EE con il linguaggio Java e in particolare con JDK 1.4.2_11 e Jakarta Tomcat 5.0.27 come Web container.
Caso pratico: verifica del codice fiscale
Vediamo adesso l‘anatomia del modello AJAX calato su un esempio pratico: la verifica della correttezza di un codice fiscale digitato da un utente.
I passi che vengono eseguiti in un‘iterazione AJAX (come illustrato in figura 5) sono i seguenti:
- Gestione di un evento sulla pagina web (onkeyup).
- Creazione ed inizializzazione dell‘oggetto XMLHttpRequest.
- Il server processa la richiesta con una servlet (codiceFiscaleValidationServlet).
- Il client processa la risposta del server (validateCallback).
- Il client aggiorna la pagina web.
Qui di seguito verranno analizzati in dettaglio i vari punti.
1. Gestione di un evento sulla pagina web (onkeyup)
Nella pagina web, il campo codicefiscale intercetta l‘evento onkeyup: ad ogni pressione di tasto viene richiamata la funzione javascript validate().
L‘evento è di solo esempio: in una mappa più complessa con molti campi di input sicuramente è meglio gestire gli eventi onchange oppure onblur.
2. Creazione ed inizializzazione dell‘oggetto XMLHttpRequest
Il corpo della funzione validate è il cuore del motore AJAX.
Per prima cosa, legge i parametri della FORM:
// Leggo il parametro della FORMvar cf = document.getElementById("codicefiscale");
e definisce alcune variabili di appoggio:
// URL del server da richiamare per la validazionevar url = "codiceFiscaleValidationServlet"; // Funzione che verra‘ richiamata al ritornovar callback = validateCallback;
In seguito, viene istanziato l‘oggetto XMLHttpRequest. Questo si deve fare in modo diverso in base al browser utilizzato: con Mozilla, Firefox e Safari, l‘oggetto XMLHttpRequest è definito nel linguaggio javascript, mentre con Internet Explorer deve essere caricato un opportuno Acvitex (diverso inoltre tra versioni precedenti alla 5.5 o superiore).
// Istanza dell‘oggetto XMLHttpRequestvar xmlhttp = false;// Se Mozilla, Firefox, Opera, Safariif (window.XMLHttpRequest) {xmlhttp = new XMLHttpRequest();// Se IE} else if (window.ActiveXObject) {try {// Versione 5.5 o inferiorexmlhttp = new ActiveXObject("Msxml2.XMLHTTP");} catch (e) {try {// Versione 5.5 o superiorexmlhttp = new ActiveXObject("Microsoft.XMLHTTP");} catch (e) {}}} // Se oggetto non istanziato: errore if (!xmlhttp) {alert("ERRORE: AJAX non supportato da questo browser!");return false;}
Viene impostato il modo di colloquio con il server: verrà invocato l‘url specificato tramite una POST in modo asincrono (terzo parametro impostato a true).
// Apro la connessione verso il server in modo asincronoxmlhttp.open(‘POST‘, url, true);
Il colloquio può anche essere fatto via HEAD o via GET.
Poi si definisce la funzione javascript di ritorno che verrà richiamata alla fine dell‘esecuzione della parte server.
// Il ritorno viene intercettato da questa funzione xmlhttp.onreadystatechange = function () {// 4 significa completatoif (xmlhttp.readyState == 4) {// Codice di ritorno del server: 200 vuol dire OKif (xmlhttp.status == 200) {// Leggo il ritorno in formato XML if (callback) {callback(xmlhttp.responseXML);}} else if (xmlhttp.status == 404) {alert("ERRORE: L‘url richiesto non esiste!");} else {alert("ERRORE: Codice di ritorno=" + xmlhttp.status);}}}
L‘attributo readyState dell‘oggetto XmlHttpRequest contiene lo stato di esecuzione della chiamata fatta al server; i valori possibili sono i seguenti:
0 = non inizializzato
1 = in caricamento
2 = caricato
3 = interattivo
4 = completato
L‘attributo status dell‘oggetto XmlHttpRequest contiene lo stato di ritorno del protocollo HTTP; alcuni valori sono:
200 = richiesta valida
404 = url inesistente
L‘attributo responseXML dell‘oggetto XmlHttpRequest contiene il tracciato XML DOM compatibile, altrimenti l‘attributo responseText contiene la risposta in formato testo.
Viene dichiarato il tipo di Header del messaggio:
// Codifica dei campi secondo il MIME type correttoxmlhttp.setRequestHeader(‘Content-Type‘, ‘application/x-www-form-urlencoded‘);
e infine viene richiamato il server, facendo attenzione a convertire i caratteri dei parametri nella codifica valida per internet:
// Invio i parametrixmlhttp.send(‘codicefiscale=‘ + encodeURIComponent(cf.value));
Se il colloquio con il server non viene fatto via POST ma via GET allora, si deve preparare un url con tutti i parametri concatenati e poi richiamare il metodo send o con null o con stringa vuota, ossia:
// URL del server da richiamare per la validazionevar url = "codiceFiscaleValidationServlet?codiceficale=" +encodeURIComponent(cf.value);// Apro la connessione verso il server in modo asincronoxmlhttp.open(‘GET‘, url, true);// Invio i parametrixmlhttp.send(null);
Si deve anche notare che l‘oggetto XmlHttpRequest viene eseguito all‘interno del browser e pertanto adotta le stesse policy di sicurezza del linguaggio javascript.
3. Il server processa la richiesta con una servlet (codiceFiscaleValidationServlet)
Il server legge i parametri ricevuti dal client:
String codiceFiscaleParam = request.getParameter("codicefiscale");
Prepara l‘output in formato XML:
request.setCharacterEncoding("UTF-8");response.setContentType("text/xml");
Inoltre, si faccia particolare attenzione anche a gestire in modo corretto la cache del browser in modo che non vengano salvate le informazioni sul client.
response.setHeader("Cache-Control", "no-cache");
Infine viene verificata la correttezza del codice fiscale:
CodiceFiscale cf = new CodiceFiscale();boolean retValue = false;try {retValue = cf.verifica(codiceFiscaleParam);} catch (CodiceFiscaleException e) {}if (retValue) {response.getWriter().write("true ");} else {response.getWriter().write("false ");}
La servlet restituisce un messaggio XML contenente true nel caso in cui sia valido, altrimenti false.
4. Il client processa la risposta del server (validateCallback)
Al ritorno sul browser, viene richiamata la funzione javascript validateCallback:
var msg = responseXML.getElementsByTagName("valid")[0].firstChild.nodeValue;
e viene letto il messaggio di ritorno dal tracciato XML.
5. Il client aggiorna la pagina web
A questo punto, viene aggiornata la pagina HTML:
var mdiv = document.getElementById("message");if (msg == "false") {// Codice Fiscale non validomdiv.className = "bp_invalid";mdiv.innerHTML = "Codice Fiscale non valido!";var submitBtn = document.getElementById("submit_btn");submitBtn.disabled = true;} else {// Validomdiv.className = "bp_valid";mdiv.innerHTML = "Codice Fiscale corretto";var submitBtn = document.getElementById("submit_btn");submitBtn.disabled = false;} }
scrivendo in rosso se il codice fiscale è errato (Figura 6), in verde se corretto (Figura 7).
Pro e contro
L‘utilizzo di AJAX, così come ogni altra tecnologia, presenta una serie di vantaggi e di svantaggi.
Vantaggi
- Meno traffico di rete tra i client e il server in quanto viaggiano solo i dati necessari al riempimento degli oggetti della pagina web.
- E‘ cross-platform, ossia è indipendente dal Sistema Operativo e pertanto è supportata su Windows, Linux e Mac.
- E‘ cross-browser, ossia tutti i browser più diffusi (Mozilla, Firefox, Opera, Safari, Internet Explorer) supportano questa modalità .
- E‘ indipendente dalla tecnologia del server, e pertanto può facilmente convivere con altre tecnologie già utilizzate per la creazione delle pagine web o per la navigazione (come Struts, Java Server Faces, ecc.).
Svantaggi:
- Problemi di refresh della pagina web nel caso in cui l‘utente prema il pulsante di “indietro” del browser.
- La ricostruzione di una pagina web può risultare complessa.
- Internet Explorer richiede che sia possibile eseguire un componente Activex per istanziare l‘oggetto XMLLHttpRequest (impostazioni di sicurezza del browser)
- L‘utilizzo di javascript sulla pagina web comporta una più difficile fase di debugging in fase di realizzazione.
Contenuto del file zippato di esempio
Qui di seguito viene data una breve descrizione del contenuto del file zippato di esempio ajax_codicefiscale.zip.
./build.xml:
Script di ANT per compilare le classi, generare il JAR, il WAR e fare il deploy su Tomcat.
./classes
Directory che contiene i compilati.
./dd/war/WEB-INF/web.xml
Descrittore del Web Container.
./lib/ajax_codice_fiscale.jar
Pacchetto delle classi compilate.
./src/java
Sorgenti java.
./src/web
Pagine web. In particolare, index.jsp contiene tutta la parte relativa ad AJAX discusse in questo articolo.
./tmp/ajax_codice_fiscale.war
Il pacchetto WAR per il deploy.
Utilizzo dell‘esempio
Per chi vuole subito vedere l‘esempio, è sufficiente copiare il file ajax_codice_fiscale.war all‘interno della cartella webapps di Jakarta-Tomcat, lanciare Tomcat e aprire il link http://localhost:8080/ajax_codice_fiscale/
Per chi, invece, vuole compilare i sorgenti e rigenerare il pacchetto WAR, può utilizzare i seguenti comandi di ANT previsti nello script:
# ant all
Per compilare e generare il file WAR.
# ant tomcat.deploy
Per effettuare il deploy.
# ant tomcat.run
Per lanciare Jakarta-Tomcat.
Conclusioni
In questo articolo sono stati affrontati i concetti basilari di AJAX necessari per comprendere al meglio questo nuovo approccio.
Bibliografia
[1] Nicholas C. Zakas, Jeremy McPeak, Joe Fawcett – “Professional Ajax”, Wrox, 02/2006
[2] Jesse James Garrett – “Ajax: A New Approach to Web Applications”
http://www.adaptivepath.com/publications/essays/archives/000385.php
[3] Brett McLaughlin – “Mastering Ajax, Part 1: Introduction to Ajax”
http://www-128.ibm.com/developerworks/java/library/wa-ajaxintro1.html
[4] Brett McLaughlin – “Mastering Ajax, Part 2: Make asynchronous requests with JavaScript and Ajax”
http://www-128.ibm.com/developerworks/java/library/wa-ajaxintro2/index.html
[5] Brett McLaughlin – “Mastering Ajax, Part 3: Advanced requests and responses in Ajax”
http://www-128.ibm.com/developerworks/java/library/wa-ajaxintro3/index.html
[6] Brett McLaughlin – “Mastering Ajax, Part 4: Exploiting DOM for Web response”
http://www-128.ibm.com/developerworks/java/library/wa-ajaxintro4/index.html
[7] “AJAX Tutorial”
http://www.w3schools.com/ajax/default.asp
[8] Apple, “Dynamic HTML and XML: The XMLHttpRequest Object”
http://developer.apple.com/internet/webcontent/xmlhttpreq.html
Risorse
[1] JDK 1.4.2
http://java.sun.com/j2se/1.4.2/download.html
[2] ANT
http://ant.apache.org/
[3] Jakarta Tomcat
http://jakarta.apache.org/
[4] Esempio zippato
ajax_codicefiscale.zip