Prerequisiti: conoscenza del linguaggio Java ed esperienza nello sviluppo di applicazioni JSP.
Introduzione
Come succede per l’HTML, anche nel caso delle pagine JSP, la costruzione avviene tramite l’utilizzo di tag e di scriptlet racchiuse tra <% ... %>. A disposizione degli sviluppatori JSP esistono moltissime librerie di tag, che permettono di svolgere funzionalità quali l’utilizzo di componenti bean, azioni di redirect verso altre pagine, come <jsp:forward ...>, e così via.
Sebbene queste librerie costituiscano tutto quanto è necessario alla costruzione di applicazioni web dinamiche, dopo un po’ ci si accorge di duplicare comunque più volte lo stesso codice e le stesse funzionalità. Le librerie di tag sono la risposta a questa esigenza di riutilizzo.
Cosa sono le Tag Libraries?
Le librerie di tag sono uno strumento messo a disposizione dalle specifiche JSP 1.1 che permette di costruire contenitori di tag JSP, e cioè contenitori di componenti con funzionalità riutilizzabili. A questo punto è però lecito chiedersi se non sia proprio questo il compito dei JavaBeans. La risposta è che JavaBeans e tag JSP hanno funzionalità e contesti di utilizzo in generale diversi.
Entrambi sono componenti Java che permettono di incapsulare codice riutilizzabile; vediamo però quando è più opportuno utilizzare gli uni oppure gli altri.
I JavaBeans server-side sono componenti non visuali e generalmente vengono destinati al mantenimento di informazioni di sessione, per esempio lo stato dell’utente all’interno di un oggetto User, oppure un carrello degli acquisti nel caso di applicazioni di e-commerce.
I tag JSP possono interagire con la pagina e si tende ad utilizzarli per incapsulare funzionalità di generazione dinamica di HTML, per esempio la tabella HTML di visualizzazione del carrello degli acquisti, oppure di controllo del percorso di navigazione in base alle informazioni di sessione, per esempio il controllo del login da inserire in cima alle pagine personali del sito.
Una delle differenze chiave tra tag JSP e JavaBeans consiste nella maggiore interazione che i tag hanno con il contesto, la pagina ma anche l’application server tramite l’oggetto ServletContext, all’interno del quale vengono utilizzati. Possono utilizzare questa interazione per accedere ad informazioni di sessione, per fare uso di JavaBeans contenenti informazioni sullo stato attuale dell’utente e o dell’applicazione e per accedere a risorse esterne come i file.
Riassumiamone le caratteristiche
In sostanza, i tag JSP possono:
- essere customizzati tramite attributi passati dalla pagina chiamante sia staticamente che con valori calcolati dinamicamente;
- ottenere l’accesso a tutti gli oggetti disponibili nelle pagine JSP come
request, response ed out;
- modificare la risposta generata dalla pagina chiamante;
- comunicare con altri tag, creare ed inizializzare componenti JavaBean, modificare un bean in un tag e poi riutilizzarlo in un altro tag;
- essere nidificati l’uno con l’altro;
- incapsulare caratteristiche sia semplici che complicate attraverso una sintassi facile da usare e che semplifica enormemente la leggibilità di una pagina JSP.
Per pagina chiamante intendiamo la pagina JSP all’interno della quale i tag vengono inseriti.
La composizione di una libreria di tag
Una tag library è costituita da due componenti: un Tag Library Descriptor, cioè il file TLD, ed il Tag Handler, cioè la classe Java che ne implementa le funzionalità.
Il file TLD
Un file TLD è un documento XML che descrive la libreria. Contiene informazioni riguardanti sia la libreria nel suo complesso che il singolo tag. Viene utilizzato dal JSP container per effettuare la validazione dei tag.
Tipicamente troveremo un’intestazione seguita da elementi di definizione globale della libreria. Tali elementi sono:
<taglib>: la libreria
<tlibversion>: la versione della libreria
<jspversion>: le specifiche JSP sulle quali la libreria si basa
<shortname>: un nome di default semplice e mnemonico; lo shortname può essere usato per esempio come prefisso per i tag contenuti
<uri>: una URI opzionale che identifichi univocamente la libreria
<info>: informazioni descrittive sulla libreria
Successivamente viene descritto ogni tag contenuto nella libreria. Una libreria può contenerne uno o più; l’unico elemento richiesto obbligatoriamente per ogni tag è la classe che lo implementa, l’handler, inclusa nell’elemento <tagclass>.
Se ci sono attributi associati, per ogni attributo avremo, all’interno dell’elemento <tag>, un elemento del tipo:
<attribute>
<name>tagname</name>
<required>true/false</required>
<rtexpvalue>true/false</rtexpvalue>
</attribute>
Nella classe handler vanno definiti metodi get e set relativi ad ogni attributo specificato con le stesse convenzioni usate nei JavaBeans.
Un esempio concreto
Passiamo adesso a presentare un semplice esempio concreto dell’utilizzo di questa tecnologia. Prenderemo in esame un semplice tag che implementa il classico esempio Hello World rivisitato con custom tag. Successivamente mostreremo come effettuare il deployment all’interno dell’application server e come utilizzarlo all’interno delle pagine.
L’application server utilizzato per l’esempio è l’implementazione di riferimento delle specifiche Servlet/JSP, Tomcat dell’Apache Group. L’esempio seguente è stato testato sulla versione 4.0. Per evitare di creare una nuova applicazione, installeremo ed utilizzeremo il nostro componente all’interno dell’applicazione di esempio situata nella directory webapps/examples all’interno del percorso di installazione di Tomcat, TOMCAT_HOME.
Partiamo dal file TLD che chiameremo mokalib.tld; il file deve essere salvato nella directory %TOMCAT_HOME%/webapp/examples/WEB-INF.
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<taglib>
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>mokalib</shortname>
<uri>http://www.mokabyte.it/taglib</uri>
<info>Mokabyte: Esempio di Tag Library</info>
<tag>
<name>wellcome</name>
<tagclass>mokabyte.examples.Wellcome</tagclass>
<bodycontent>empty</bodycontent>
<info>Il classico esempio "Hello World" rivisitato con i Tag.</info>
<attribute>
<name>name</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
</taglib>
Il valore di <bodycontent> può essere:
empty: nessun body
JSP: il contenuto del body è valutato dal container e processato dal tag handler
tagdependent: il contenuto del body viene processato solo dal tag handler; il codice JSP contenuto nel body non viene valutato dal container
Il Tag Handler
Il tag viene definito in una classe denominata handler che estende la classe base astratta TagSupport. Sarà chiaramente necessario implementare i metodi non implementati nella classe astratta e fornire i metodi get e set relativi alle proprietà che vogliamo attribuire al nostro oggetto tag.
Se il tag non ha attributi ed il body è vuoto, cioè non c’è niente compreso tra l’apertura e la chiusura del tag, sarà necessario implementare doStartTag e doEndTag.
Se invece ha degli attributi e non ha un body, sarà necessario implementare doStartTag, doEndTag e i metodi set/getAttribute1...N.
Nel nostro caso avremo una sola proprietà, name, e quindi dovremo implementare i quattro metodi doStartTag, doEndTag, setName(String value) e getName().
Passiamo adesso all’analisi del codice Java corrispondente. Chiamiamo il file Wellcome.java. Una volta compilato, verrà generato il file %OUTDIR%/mokabyte/examples/Wellcome.class. Sarà necessario copiare l’intera struttura in %TOMCAT_HOME%/webapp/examples/WEB-INF/classes affinché sia disponibile nel classpath dell’applicazione examples di Tomcat.
package mokabyte.examples;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
/**
* Un semplice esempio di Tag JSP per comprendere cosa viene inserito nello
* output stream quando il tag viene inserito in una pagina JSP.
*/
public class Wellcome extends TagSupport {
private String name = null;
/**
* Metodi get/set per l’attributo name come definito nel file TLD.
*/
public void setName(String value) {
name = value;
}
public String getName() {
return name;
}
/**
* doStartTag viene chiamato dal JSP container quando il tag viene trovato.
*/
public int doStartTag() {
try {
JspWriter out = pageContext.getOut();
out.println("<table border=\"1\">");
if (name != null)
out.println("<tr><td> Benvenuto/a " + name + " </td></tr>");
else
out.println("<tr><td> Benvenuto a chi? </td></tr>");
} catch (Exception ex) {
throw new Error("Qualcosa è andato storto.");
}
// Dovrò ritornare SKIP_BODY perché il body è vuoto,
// come specificato nel file TLD.
return SKIP_BODY;
}
/**
* doEndTag viene chiamato dal JSP container quando viene
* trovato il segno di chiusura del tag.
*/
public int doEndTag() {
try {
JspWriter out = pageContext.getOut();
out.println("</table>");
} catch (Exception ex) {
throw new Error("Qualcosa è andato storto.");
}
return EVAL_PAGE;
}
}
Registriamo la libreria
L’operazione di registrazione della libreria permette di comunicare all’application server la URI, in realtà è sufficiente una URI qualsiasi purché univoca, e la locazione del file TLD associati con la libreria.
Nel file web.xml, inseriamo il testo seguente alla sezione <taglib>:
<taglib>
<taglib-uri>
http://www.mokabyte.it/taglib
</taglib-uri>
<taglib-location>
/WEB-INF/mokalib.tld
</taglib-location>
</taglib>
Scriviamo la pagina `wellcome.jsp`
<%@ taglib uri="http://www.mokabyte.it/taglib" prefix="moka" %>
<html>
<head>
<title>Il mio primo Tag JSP</title>
</head>
<body bgcolor="#ffffff">
<hr />
<moka:wellcome name="Michele"/>
<hr />
</body>
</html>
Salviamo la pagina Wellcome.jsp in %TOMCAT_HOME%/webapp/examples/.
Adesso possiamo lanciare l’application server Tomcat. Se tutto è andato bene, potrete vedere l’output alla URL http://localhost:8080/examples/wellcome.jsp.
Facendo click destro sul browser ed andando a visualizzare il sorgente HTML, il risultato dovrebbe essere il seguente:
<html>
<head>
<title>Il mio primo Tag JSP</title>
</head>
<body bgcolor="#ffffff">
<hr />
<table border="1">
<tr><td>Benvenuto Michele.</td></tr>
</table>
<hr />
</body>
</html>
L’esempio mostra bene il vantaggio delle custom tag library: incapsulare logica di presentazione riutilizzabile dietro una sintassi semplice, leggibile e integrata nel linguaggio JSP.