Tarin Gamberini

A software engineer and a passionate java programmer

Come lavorare con la JSTL

Oltre ai tag html esistono anche i custom tag JSP, conosciuti anche come tag personalizzati, che sono sostanzialmente legati alla tecnologia JSP. In altre parole i tag personalizzati sono utilizzati nell'implementazione di web application che adottano la tecnologia JSP per la progettazione di pagine web.

Un tag personalizzato incapsula una funzionalità implementata da una classe java detta tag handler. Alcuni vantaggi derivanti da tale approccio sono:

  • la pagina JSP risulta più leggibile: invece che presentare codice html inframezzato da scriplet java, essa presenta tag html e tag personalizzati;
  • un tag personalizzato è riusabile: la funzionalità contenuta nella classe tag handler è richiamabile più volte all'interno di pagine JSP.

La JavaServer Pages Standard Tag Library (JSTL) è una raccolta di tag che gestiscono: controllo di flusso condizionale ed iterativo, manipolazione di file XML, accesso a database tramite SQL, ed altre comuni funzionalità.

Indice

Cosa serve per lavorare con la JSTL

Per lavorare con la JSTL occorre avere un'opportuna distribuzione di tale libreria. Nel corso di questo breve articolo faremo riferimento alla JavaServer Pages Standard Tag Library versione 1.1. Essa richiede un container JSP che supporti le specifiche Java Servlet versione 2.4 e JavaServer Pages versione 2.0 come, per esempio, Tomcat 5.5.

Le JSP versione 2.0 supportano un Expression Language (EL) [1] in grado di valutare espressioni aritmetico-logiche e di accedere agilmente alle proprietà dei bean. Affinché una espressione EL sia valutata occorre indicarla fra i simboli ${ e }.

Configurare la JSTL in una applicazione web

Affinché una una pagina JSP possa utilizzare un tag personalizzato della JSTL occorre configurare opportunamente i componenti [2] della tag library:

  • il tag handler
  • il tag library descriptor

Il Tag Handler

Il tag handler è una classe java il cui codice implementa il comportamento del tag. Nella distribuzione JSTL versione 1.1 i tag handler si trovano nel file jstl.jar, che deve essere copiato nella directory /WEB-INF/lib della propria web application.

Il Tag Library Descriptor

Il file Tag Library Descriptor (TLD) è il descrittore della libreria di tag. E' un file xml che contiene alcune meta-informazioni: il nome della libreria, l'uri della libreria, i nomi dei tag, i nomi dei relativi tag handler, ecc… A titolo puramente indicativo riportiamo un breve estratto dal descrittore c.tld della libreria core:

c.tld
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<taglib ... >
 <description>JSTL 1.1 core library</description>
 <display-name>JSTL core</display-name>
 <tlib-version>1.1</tlib-version>
 <short-name>c</short-name>
 <uri>http://java.sun.com/jsp/jstl/core</uri>
 ...
 <tag>
  <description>
   Simple conditional tag, which evalutes
   its body if the supplied condition is
   true and optionally exposes a Boolean
   scripting variable representing the
   evaluation of this condition
  </description>
  <name>if</name>
  <tag-class>org.apache.taglibs.standard.tag.rt.core.IfTag</tag-class>
  ...
 </tag>
 ...
</taglib>

I file TLD devono essere copiati in una cartella della propria applicazione web: tipicamente /WEB-INF/tld.

Il Deployment Descriptor

Il file web.xml deve obbligatoriamente essere configurato solo se si utilizza una versione inferiore alla JSP 1.2 [3]. Infatti a partire dalla versione 1.2, all'avvio del server, il container va automaticamente alla ricerca dei TLD contenuti nell'albero WEB-INF e contenuti nei jar. Preleva poi l'uri dal TLD e memorizza in una java.util.Map il nome di ogni tag associandolo al relativo tag handler.

Pertanto per versioni inferiori alla JSP 1.2 occorre indicare nel descrittore di deploy della web application quali librerie vogliamo utilizzare. Nell'ipotesi di utilizzare solamente la core library scriveremo nel web.xml il seguente codice:

web.xml
1
2
3
4
5
6
7
8
<web-app>
 ...
 <taglib>
  <taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>
  <taglib-location>/WEB-INF/tld/c.tld</taglib-location>
 </taglib>
   ...
</web-app>

La taglib-location deve indicare il descrittore di libreria attraverso un percorso relativo. Il taglib-uri indica una nome simbolico utilizzato nelle pagine JSP per importare la libreria. Il taglib-uri deve essere un nome univoco all'interno dell'intera applicazione web. Per cercare di garantire tale unicità i produttori di TLD hanno adottato la convenzione di utilizzare come uri un indirizzo http, per esempio: http://java.sun.com/jsp/jstl/core.

In altre parole nel web.xml ogni taglib mappa un uri ad un TLD.

La pagina JSP

Nella pagina JSP in cui si desidera utilizzare una tag library, per esempio la core, si deve usare la direttiva:

1
2
3
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
...

in cui l'uri coincide con il nome simbolico indicato nel tag taglib-uri del web.xml. La JSP non cerca il TLD in internet, quest'ultimo è già stato caricato dal container all'avvio del server ed è pertanto già disponibile alla JSP.

Dichiarare la versione del web.xml

Un altro problema che può incontrare lo sviluppatore che si avvicina per le prime volte alla JSTL versione 1.1, e quindi indirettamente alle JSP versione 2.0, è quello di non vedere interpretate le espressioni EL. Per esempio supponiamo di aver creato la pagina index.jsp seguente:

index.jsp
1
2
3
4
5
6
7
8
9
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
 <head>
  <title>Esercitazione con JSP 2.0</title>
 </head>
 <body>
  ${ 3 + 2 }
 </body>
</html>

Richiedendo la pagina al server potrebbe accadere che il browser riceva un risposta visualizzata come:

${ 3 + 2 }

mentre ci si sarebbe aspettato che il server, interpretando l'espressione EL, rispondesse con una pagina così:

5

Per risolvere questo problema si deve dichiarare la versione del web.xml. La valutazione delle espressioni EL, infatti, dipende della versione del descrittore di deploy della web application [4].

Tomcat 5.5, che ricordiamo supporta le specifiche Java Servlet versione 2.4 e JavaServer Pages versione 2.0, lascia la possibilità al progettista di definire la versione del descrittore di deploy. Definendo nel web.xml il tag web-app senza versione:

web.xml
1
2
3
4
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
    ...
</web-app>

Tomcat 5.5 considererà il descrittore di deploy di versione 2.3, pertanto le espressioni EL non saranno valutate. Definendo nel web.xml il tag web-app con versione 2.4:

web.xml
1
2
3
4
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4">
    ...
</web-app>

o per maggior completezza:

web.xml
1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF-8"?>
<web-app
  xmlns="http://java.sun.com /xml/ns/j2ee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="
    http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
  version="2.4">
...
</web-app>

Tomcat 5.5 considererà il descrittore di deploy di versione 2.4, pertanto le espressioni EL saranno valutate.

Se, anche dopo aver configurato il web.xml con <web-app version="2.4">, si continuasse ad ottenere una pagina in cui le espressioni EL non fossero valutate si legga la sezione Tomcat e la directory di lavoro: work.

Tomcat e la directory di lavoro: work

L'ambiente in cui stiamo sviluppando l'applicazione avrà definito una directory di lavoro in cui Tomcat 5.5, sfruttando Jasper, tradurrà le pagine JSP in servlet. Tipicamente tale directory è chiamata col nome work.

Supponiamo di aver configurato il descrittore di deploy di versione 2.3, cioè con <web-app>, e di aver richiesto la pagina index.jsp. Nella directory di lavoro esisterà una servlet, con un nome simile ad index_jsp.java, le cui espressioni EL non saranno state tradotte da Tomcat.

Ora correggiamo il web.xml con <web-app version="2.4">, riavviamo il server e richiediamo nuovamente la pagina index.jsp. Tomcat 5.5 controlla la directory di lavoro accorgendosi che index.jsp non è stata modificata dall'ultima richiesta, quindi non ritradurrà la JSP in una servlet ma riuserà quella precedentemente ottenuta con il descrittore di deploy di versione 2.3. In altre parole, anche dopo aver configurato il web.xml con <web-app version="2.4"> si osserverà una pagina ottenuta senza valutazione delle espressioni EL.

Per risolvere questo problema è sufficiente cancellare il contenuto della directory di lavoro.

Riavviamo il server e richiediamo la pagina index.jsp. Tomcat 5.5 controlla la directory di lavoro accorgendosi che index.jsp è assente, quindi la tradurrà in una servlet ma considerando il web.xml appena corretto con <web-app version="2.4">. Pertanto si osserverà finalmente una pagina ottenuta con la valutazione delle espressioni EL.

Per completezza riportiamo un breve estratto della servlet index_jsp.java tradotta da Jasper a partire dalla index.jsp, avviando il server quando il web.xml è configurato con <web-app>:

index_jsp.java
1
2
3
4
5
6
7
8
9
10
11
12
...
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class index_jsp
  extends org.apache.jasper.runtime.HttpJspBase
  implements org.apache.jasper.runtime.JspSourceDependent {
  ...
  out.write("${ 3 + 2 }");
  ...
}

Si osserva che, nella scrittura della response, l'espressione EL non viene valutata. Analogamente riportiamo un breve estratto della servlet index_jsp.java quando il web.xml è configurato con <web-app version="2.4">:

index_jsp.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
...
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;

public final class index_jsp
  extends org.apache.jasper.runtime.HttpJspBase
  implements org.apache.jasper.runtime.JspSourceDependent {
  ...
  out.write((java.lang.String)
    org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate(
      "${ 3 + 2 }",
      java.lang.String.class,
      (PageContext)_jspx_page_context,
      null,
      false)
    );
  ...
}

osservando che, nella scrittura della response, l'espressione EL è valutata invocando il metodo proprietaryEvaluate.

La direttiva isELIgnore

Se la propria web application è conforme alle specifiche Java Servlet versione 2.3 ed esegue all'interno di un container che supporta le specifiche Java Servlet versione 2.4 è comunque possibile ricorrere alle espressioni EL dichiarando all'interno della pagina JSP la direttiva isELIgnore:

1
2
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@page isELIgnored ="false" %>

Tale direttiva sovrascrive l'impostazione per l'interpretazione delle espressioni EL che il container aveva caricato dal descrittore di deploy all'avvio del server.

In questo modo è garantita la retro-compatibilità della JSTL con applicazioni il cui web.xml sia di versione 2.3 od inferiore [5].

Bibliografia

[1]
The J2EE ™ 1.4 Tutorial - For Sun Java System Application Server Platform Edition 8.2 - Eric Armstrong, Jennifer Ball, Stephanie Bodoff, Debbie Bode Carson, Ian Evans, Dale Green, Kim Haase, Eric Jendrock - 7 Dicembre 2005 - Capitolo 12 “JavaServer Pages Technology” - Paragrafo “Expression Language” - pag 499
[2]
Programmare con Jakarta Struts - Chuck Cavaness - Ulrico Hoepli Editore - Capitolo 8 “Librerie di Tag JSP personalizzati” - Paragrafo “Che cosa è una libreria di tag?” - pag 190
[3]
Java Server Pages - 3^ edizione - Hans Bergsten - Editore Hops-Tecniche Nuove - Capitolo 7
[4]
The J2EE ™ 1.4 Tutorial - For Sun Java System Application Server Platform Edition 8.2 - Eric Armstrong, Jennifer Ball, Stephanie Bodoff, Debbie Bode Carson, Ian Evans, Dale Green, Kim Haase, Eric Jendrock - 7 Dicembre 2005 - Capitolo 12 “JavaServer Pages Technology” - Paragrafo “Deactivating EL Expression Evaluation” - pag 522
[5]
The J2EE ™ 1.4 Tutorial - For Sun Java System Application Server Platform Edition 8.2 - Eric Armstrong, Jennifer Ball, Stephanie Bodoff, Debbie Bode Carson, Ian Evans, Dale Green, Kim Haase, Eric Jendrock - 7 Dicembre 2005 - Capitolo 12 “JavaServer Pages Technology” - Paragrafo “Deactivating Expression Evaluation” - pag 500

Invia un commento

Un commento è inviato attraverso una normalissima e-mail. Il tuo indirizzo e-mail non sarà pubblicato o diffuso.

Questo blog è moderato, per cui alcuni commenti potrebbero non essere pubblicati. I commenti sono solitamente approvati dal moderatore in uno/tre giorni.