In occasione del passato JavaOne 1998, la manifestazione dedicata a Java organizzata da Sun a San Francisco, furono presentate molte novità legate a questo linguaggio, fra cui le Java Server Pages.

Inizialmente sono passate un po’ in sordina agli occhi della comunità di sviluppatori, e solo con il rilascio della specifica .92 [SPEC092] si è iniziato a sentirne parlare un po’ più spesso: questo ritardo nella diffusione di tali oggetti si deve imputare anche alla mancanza, i primi tempi, di software col quale poter effettuare prove e sviluppare applicazioni.

In questo articolo si cercherà di introdurre le basi di questa nuova ed interessantissima tecnologia, che molto probabilmente giocherà un ruolo fondamentale nell’evoluzione del web futuro: dato però che si tratta di una soluzione relativamente giovane, per assistere a una completa affermazione sarà necessario attendere ancora un poco.

A causa della vastità dell’argomento, questo mese ci soffermeremo sulla parte legata alla tecnologia in sé, vedendo cosa sia, come funzioni e cosa ci permetta di fare. Solo successivamente prenderemo in esame alcuni esempi pratici con i quali poter risolvere problematiche concrete. In quell’occasione parleremo anche dei prodotti più interessanti per lo sviluppo e per l’utilizzo di pagine JSP, ovvero quelli della famiglia WebSphere di IBM [WebSphere].

Pagine web a contenuto dinamico

La creazione di pagine web a contenuto dinamico è uno dei settori in cui ultimamente si sta concentrando la maggior parte dell’attenzione, sia da parte delle case produttrici di software sia della comunità di programmatori.

Questo obiettivo può essere raggiunto per mezzo di molte soluzioni tecnologiche, anche se il meccanismo si basa sempre sull’estensione delle potenzialità del web server. Gli script CGI, le pagine ASP e i moduli di Apache sono solo alcune delle possibilità fra cui si può scegliere: nel caso di Java, l’estensione del web server può essere fatta, come ormai è noto, per mezzo dei servlet e, di recente, con JSP.

Per chi avesse ancora qualche dubbio sul funzionamento dei servlet, ecco un mini sunto su cosa sia un servlet e come funzioni.

  • Un servlet è a tutti gli effetti un’applicazione Java in esecuzione su una JVM residente sul server.
  • Un servlet viene invocato tutte le volte che una determinata pagina HTML, nella quale vi è inserito un riferimento, viene fatta processare dal web browser.
  • Il servlet tipicamente esegue una serie di operazioni e produce un output (codice HTML) che verrà poi inviato direttamente al client: questo non ha la percezione di cosa sia accaduto, dato che il browser riceve solamente codice HTML.

Per chi desiderasse approfondire gli argomenti legati ai servlet e alla gestione dinamica dei siti web, si possono trovare maggiori informazioni in [ServletIntro], [ServletWeb] e [SerlvetStato].

Creazione dinamica di pagine HTML significa generalmente che tutto il lavoro di produzione viene svolto sul lato server, e quindi non sono richieste particolari funzionalità aggiuntive al browser, il quale deve semplicemente essere in grado di interpretare HTML standard.

I servlet offrono una serie di vantaggi rispetto alle soluzioni concorrenti, legati al fatto che si utilizza Java come linguaggio di sviluppo. I servlet però richiedono un po’ di lavoro in più per risolvere aspetti legati al life-cycle, al mantenimento dello stato e al passaggio di parametri fra oggetti differenti. Le Java Server Pages sono state proprio pensate con lo scopo di eliminare queste limitazioni, oltre che di offrire ulteriori importanti funzionalità.

JSP: perché?

Prima di addentrarsi nei meandri della programmazione, vediamo di capire perché le JSP siano così importanti e come possano risultare utili in una situazione reale. Ecco alcuni punti chiave che dovrebbero chiarire le idee:

  • Le JSP sono la risposta a soluzioni simili come ASP, ma in chiave Java: oltre ai soliti innegabili vantaggi derivanti dall’utilizzo di Java come linguaggio, in questo caso la portabilità assume un ruolo particolarmente importante.
  • Il potersi svincolare dalla particolare piattaforma (sistema operativo e hardware) è una caratteristica molto importante in un settore, quello dei server web, in continua evoluzione. Inoltre, la sempre maggiore stratificazione in atto rende Java ancora più prezioso, dato l’utilizzo di protocolli standard di comunicazione.
  • La portabilità deve essere intesa anche dal punto di vista del client: utilizzare Java come linguaggio di script, che in ogni caso viene interpretato dal server, potrà forse contribuire alla diminuzione del proliferare dei molti linguaggi, DHTML, JavaScript e JScript, VBScript, i quali, oltre a creare confusione, spesso non sono supportati dai differenti browser in commercio.
  • L’enfasi maggiore data all’utilizzo dei componenti facilita il riuso, la portabilità e semplifica lo sviluppo. Questa visione si riallaccia a quella che è l’attuale tendenza della programmazione a oggetti utilizzata anche in ambiti più ampi.
  • Uno dei punti chiave alla base di JSP è la facilità con cui si può mantenere lo stato in una sessione HTML: questo può risultare molto utile, ad esempio, per la realizzazione di un sito basato sul commercio elettronico. Infatti i componenti (JavaBeans) incapsulati nelle pagine possono essere utilizzati per memorizzare l’insieme degli acquisti effettuati (carrello della spesa), o altre informazioni riservate come i dati relativi alla carta di credito o al conto corrente.

Cosa è Java Server Pages?

Si tratta di una tecnologia che agli occhi del programmatore viene gestita per mezzo di un linguaggio di script, e che è in grado di mescolare codice HTML, componenti riusabili (JavaBeans), applicazioni remote (servlet), codice Java e script Java-like. Si potrebbe dire che le Java Server Pages rappresentano il collante per unire insieme una serie di oggetti differenti fra loro.

Per chi conosce il mondo Microsoft, JSP è qualcosa di molto simile ad ASP, dove i componenti ActiveX sono rimpiazzati dai JavaBeans e dove l’invocazione ad applicazioni COM si trasforma in esecuzione di servlet; anche la somiglianza fra i nomi non è casuale.

La possibilità di utilizzare i componenti come parte integrante del codice HTML permette, in maniera estremamente semplice, di aumentare le potenzialità e la flessibilità senza la necessità di conoscere complessi linguaggi di programmazione come Java. È possibile inoltre inserire codice Java all’interno della pagina: questo codice verrà poi gestito dal server che provvederà alla sua compilazione ed esecuzione. Questo fatto permette al programmatore di inserire parti di codice Java in modo molto simile a come farebbe con script JavaScript, VBScript o simili.

Come conseguenza si ha un ulteriore impulso alle performance e alla portabilità, dato che il codice prodotto viene eseguito sul server e non nel browser.

Per eseguire un JSP si deve utilizzare un web server in grado di supportare tale tecnologia, oppure far uso di un cosiddetto application server che estenda le funzionalità del web server. Ad esempio JRun o WebSphere Application Server sono due prodotti molto diffusi in grado di offrire funzionalità sia per i servlet sia per JSP.

Questa soluzione è utilizzata sempre più diffusamente, dato che non obbliga a cambiare ogni volta tutto il software lato server, ma solamente ciò che è sopra il web server, consentendo in tal modo una maggiore flessibilità e possibilità di stare al passo coi tempi (vedi figura 1). Per semplicità parleremo in seguito di server senza specificare se si tratta in realtà di un web server o di un application server che ne estende le funzionalità.

Il meccanismo dell’Application Server permette di estendere le funzionalità del web server: quando un client richiede una risorsa non gestibile direttamente, come JSP o servlet, la richiesta viene passata all’application server.
Il meccanismo dell’Application Server permette di estendere le funzionalità del web server: quando un client richiede una risorsa non gestibile direttamente, come JSP o servlet, la richiesta viene passata all’application server.

Invocazione

Vediamo adesso quali sono le principali modalità di utilizzo di una Java Server Page: ci sono due possibilità.

Schema di utilizzo diretto di un JSP: il client fa riferimento direttamente alla pagina .jsp, che interagisce per mezzo di JavaBeans con database o altre risorse remote. Il risultato viene passato direttamente al client.
Schema di utilizzo diretto di un JSP: il client fa riferimento direttamente alla pagina .jsp, che interagisce per mezzo di JavaBeans con database o altre risorse remote. Il risultato viene passato direttamente al client.
  • JSP-centrica: un client esegue una richiesta direttamente a una pagina JSP, la quale, interfacciandosi con delle risorse sul lato server, produce direttamente l’output voluto (figura 2).
  • Il collegamento può avvenire per mezzo di componenti inseriti all’interno della pagina JSP, di riferimenti a servlet o di codice Java scritto nella pagina.
  • Servlet-centrica: il client effettua una richiesta a un servlet, il quale esegue le operazioni del caso e incapsula i risultati in un componente. Successivamente il servlet provvede a chiamare la pagina JSP, che preleva i dati immagazzinati nel componente e produce l’output voluto (figura 3). Anche se questa soluzione può apparire piuttosto complessa, disponendo di strumenti di sviluppo adatti rappresenta la strada che offre i risultati migliori, specie in funzione della flessibilità e della successiva customizzazione.
Schema di gestione indiretta di pagine JSP: la richiesta del client viene indirizzata a un servlet, che immagazzina i risultati in un bean e invoca un JSP per produrre l’output.
Schema di gestione indiretta di pagine JSP: la richiesta del client viene indirizzata a un servlet, che immagazzina i risultati in un bean e invoca un JSP per produrre l’output.

In entrambi i casi, la prima volta che un file JSP viene invocato, viene effettuata una compilazione del .jsp e di tutti i componenti definiti al suo interno (codice Java, script e cose del genere), dando luogo a bytecode standard: quello che prima era script diventa codice Java compilato ed eseguito all’interno del server. Conseguenza di questo meccanismo è che la prima volta che si invoca il file .jsp il sistema sarà un po’ più lento del normale, ma dalla seconda invocazione in poi si hanno prestazioni di tutto rispetto.

Server evoluti, come ad esempio WebSphere o il nuovo JavaWebServer, sono in grado di effettuare controlli sul codice sorgente e di effettuare automaticamente ricompilazioni nel caso in cui qualcosa sia cambiato. Il meccanismo della compilazione automatica di script che diviene codice binario è attualmente uno dei punti più interessanti della tecnologia Java e non solo: ad esempio la tanto famosa HotSpot di Sun potrà essere inserita in questo scenario in maniera del tutto indolore e trasparente, con un indubbio vantaggio per le prestazioni.

Il linguaggio delle JSP

L’utilizzo di JSP è molto semplice, dato che si basa fondamentalmente su Java e HTML: la struttura e la logica infatti si rifanno a quella dell’HTML, mentre la possibilità di inserire codice Java permette a tutti i programmatori Java una migrazione indolore, senza cioè la necessità di dover imparare un nuovo linguaggio di script. La possibilità di accedere e manipolare componenti (JavaBeans) all’interno della pagina stessa è uno dei punti più importanti: questo fatto influenza fortemente la modalità con cui sono definiti e utilizzati i vari tag, come vedremo di seguito.

I tag che si possono utilizzare possono essere suddivisi in due categorie:

  • Orientati al componente (Component-centric tag): elementi molto simili all’HTML, con i quali è possibile ricoprire la maggior parte delle necessità.
  • Orientati allo script (Scripting-centric tag), grazie ai quali è possibile risolvere la parte restante delle casistiche tipiche.

Tag orientati al componente

Questi tag sono molto semplici e non implicano nessun tipo di script o codice Java. Essendo tag elementari, sono molto simili all’HTML, mentre la loro organizzazione gerarchica si riconduce alla struttura oggetto-proprietà. Come nel caso dell’HTML, questi tag non sono case-sensitive e non è obbligatorio utilizzare i doppi apici per la definizione dei valori, anche se è sicuramente più elegante seguire tale formalismo.

Si è detto che uno dei punti più importanti delle JSP è la possibilità di accedere e manipolare componenti (JavaBeans) all’interno della pagina stessa: questo si traduce nella possibilità di accedere ai metodi e alle proprietà degli stessi, e tipicamente questo meccanismo avviene per mezzo di una scrittura del tipo:

nomeBean:nome_proprietà

come ad esempio:

myUserBean:address

Si noti che l’accesso ai campi (proprietà) del bean avviene per mezzo del carattere : e non .: questo allo scopo di evidenziare il fatto che non si tratta di codice Java, ma di script JSP. Oltretutto, se fosse codice Java, oltre che impossibile sarebbe formalmente scorretto accedere alle proprietà del componente direttamente senza l’ausilio di metodi get/set.

Vediamo adesso quali sono i tag più importanti per l’utilizzo di un componente all’interno della pagina. Per prima cosa i tag di specificazione del bean:

  • la coppia <USEBEAN> e </USEBEAN>, per mezzo della quale è possibile rendere disponibile il componente a tutte le invocazioni successive all’interno della pagina. Deve essere utilizzata a inizio pagina;
  • <SETONCREATE ...> è una specie di init() e serve per settare alcune proprietà al momento della creazione del componente; può essere utilizzato solo all’interno della coppia <USEBEAN>, </USEBEAN>;
  • <SETFROMREQUEST ...> serve per passare al bean un parametro arrivato come richiesta dall’esterno, con il meccanismo tipico di una GET CGI; può essere utilizzato solo all’interno della coppia <USEBEAN>, </USEBEAN>.

Per la visualizzazione delle proprietà di un bean invece possiamo utilizzare:

  • <DISPLAY ...> restituisce il valore di una proprietà a valore singolo;
  • <LOOP ...> ... </LOOP> fornisce un meccanismo ripetitivo per la visualizzazione di proprietà multiple.

Nel file LoginOut.jsp è possibile vedere come si implementa una semplice pagina che utilizza un bean precedentemente istanziato con i dati di un utente per visualizzare i dati dell’utente stesso. Come si può notare da tale esempio, si tratta di codice HTML con all’interno riferimenti a codice JSP.

Si è detto che un componente, per poter essere utilizzato, deve essere specificato per mezzo di USEBEAN. Questo non è sempre vero, dato che alcuni bean particolari sono sempre disponibili, anche senza la dichiarazione per mezzo del tag apposito. Si tratta di bean di tipo request, nel quale troviamo le informazioni relative alla richiesta inviata dal client, e di tipo exception, che invece contengono tutte le informazioni di un’eventuale eccezione.

I tag di tipo Script

L’altra tipologia di tag offerta da JSP è quella orientata allo scripting, per mezzo della quale è possibile inserire vero e proprio codice script all’interno della pagina. Questi tag si suddividono a loro volta in:

  • Direttive: sono particolari istruzioni che avvertono il JSP-Engine, ovvero il web server o application server JSP enabled, di una particolare impostazione da utilizzare. Questa sezione è aperta a future estensioni. La sintassi è <%@ ... %>.
  • Dichiarazioni: permettono la definizione di variabili a scope globale rispetto alla pagina. Le dichiarazioni si includono all’interno della coppia di tag <SCRIPT ...> ... </SCRIPT>.
  • Scriptlet: vere e proprie porzioni di codice da eseguire. Uno scriptlet deve essere inserito all’interno della coppia di tag <% ... %>.
  • Espressioni: denotate dalla sintassi <%= ... %>, permettono l’inserimento di vere e proprie espressioni, variabili valutate a run time.
  • Variabili implicite: variabili disponibili automaticamente senza la necessità di particolari inclusioni. Sono utilizzabili per mezzo della sintassi <% ... %>.

Nel file sessione.htm viene invece mostrato come uno scriptlet possa essere inserito nell’HTML. Anche in questo caso vale la considerazione fatta in precedenza: il file è a tutti gli effetti script puro che, per la presenza di direttive <% ... %>, è formalmente da considerarsi JSP.

Java Server Pages Beans

Il cuore di JSP si basa sul poter utilizzare direttamente componenti: vediamo quindi come ciò sia possibile. Per prima cosa riprendiamo in considerazione il tag USEBEAN: la sintassi completa è la seguente.

<USEBEAN NAME=nome_della_beaninstance
         TYPE=nome_del_bean
         LIFESPAN="page|session|application">
</USEBEAN>

La maggior parte di questa scrittura dovrebbe essere di facile interpretazione: NAME indica il nome simbolico con cui il bean verrà referenziato all’interno della pagina, mentre TYPE indica il file .class. Il tag LIFESPAN, che letteralmente significa periodo di vita, permette di specificare quanto tempo il bean istanziato verrà mantenuto in memoria prima della sua eliminazione. I valori permessi indicano se conservare il bean per tutto il periodo in cui la pagina viene visualizzata nel client, per la sessione (nel senso di HTTP session) o per la durata dell’applicazione.

Ovviamente bisogna tenere presente che la durata del componente è importante per i valori delle variabili in esso contenute, non tanto per il componente stesso. La figura 4 mostra il cosiddetto ciclo di vita di un componente.

Ciclo di vita del bean: quando viene referenziato in una pagina HTML, se il componente esiste viene utilizzato direttamente, altrimenti viene creato e istanziato; il lifespan definisce quanto deve vivere.
Ciclo di vita del bean: quando viene referenziato in una pagina HTML, se il componente esiste viene utilizzato direttamente, altrimenti viene creato e istanziato; il lifespan definisce quanto deve vivere.

Per visualizzare i valori di un bean si utilizza il tag DISPLAY: ad esempio il pezzo di codice JSP che segue verrà dinamicamente modificato in funzione del valore della proprietà imageURL.

<img src="<DISPLAY PROPERTY=imagesContainer:imageURL>">

Il codice HTML risultante conterrà il riferimento all’immagine voluta, come ad esempio:

<img src="title.gif">

Come si utilizza tutto ciò?

Vedremo in dettaglio il mese prossimo questo aspetto: per adesso si sappia che non sono necessarie particolari operazioni di installazione. Se si decide di fare tutto a mano, cioè senza l’ausilio di nessun wizard che assista nelle fasi di developing/deploying, dopo aver scritto tutti i file (.jsp, .html, servlet e bean) sarà necessario eseguire queste semplici operazioni:

  • copiare i .class corrispondenti ai servlet nella directory standard in modo che l’Application Server li possa “vedere”. I .class corrispondenti ai vari bean e alle classi di supporto dovranno essere installati sul server in funzione della configurazione della macchina, essenzialmente dove il CLASSPATH permette la loro localizzazione;
  • mettere tutti i file .html e .jsp in una directory qualsiasi che sia mappata in modo da essere accessibile via client per mezzo di una URL.

Praticamente niente altro è necessario, oltre alle ovvie configurazioni necessarie per permettere il funzionamento dei vari pezzi Java, come sorgenti ODBC-JDBC e RMI registry ove necessario.

Conclusione

Prima di congedarmi e rimandare la conclusione con esempi pratici al mese prossimo, vorrei ricordare che JSP è una tecnologia relativamente giovane, che proprio per questo ancora non è pienamente supportata e quindi non è facile al momento reperire materiale informativo a tal proposito. Quando mi sono trovato a fare le prime prove, mi sono imbattuto in non poche difficoltà, anche se adesso la situazione è nettamente migliorata.

Quello che però ancora manca è un supporto altamente semplificato per lo sviluppo di tali oggetti: JSP infatti renderà la vita molto più semplice al programmatore solo se questo potrà disporre di adeguati strumenti automatizzati per lo sviluppo, cosa che ad esempio accade in ambito Microsoft con le Active Server Pages. Vedremo quanto le varie aziende vorranno investire in questa direzione.

Bibliografia

  • -
  • [SPEC092] Java Server Pages Specifications — http://java.sun.com/products/jsp/index.html
  • -
  • [ServletIntro] “Java Servlet” di Fabrizio Giudici — MokaByte 11, settembre 1998 (www.mokabyte.it/0998)
  • -
  • [ServletWeb] “Servlet, JDBC e JavaServer: quando l’unione fa la forza (e semplifica la vita)” di Giovanni Puliti — MokaByte 20, giugno 1998 (www.mokabyte.it/0698)
  • -
  • [SerlvetStato] “Gestire le sessioni con le servlet” di Gerardo Poggiali — MokaByte 26, gennaio 1999 (www.mokabyte.it/0199)
  • -
  • [JWS] JavaWeb Server 1.2 — http://www.sun.com/software/jwebserver/index.html
  • -
  • [WebSphere] WebSphere Application Server e Studio — www.software.ibm.com/WebSphere; http://www.software.ibm.com/webservers/appserv/doc/as2wksta.html