Skip to content

8. La libreria di tag JSTL

8.0.1. Introduzione

Si consideri la vista [erreurs.jsp], che visualizza un elenco di errori:

Image

Esistono diversi modi per scrivere una pagina di questo tipo. In questo caso, ci interessa solo la parte relativa alla visualizzazione degli errori. Una soluzione consiste nell'utilizzare il codice Java come è stato fatto:


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ page import="java.util.ArrayList" %>
 
<%
// on récupère les données du modèle
  ArrayList erreurs=(ArrayList)request.getAttribute("erreurs"); 
  String lienRetourFormulaire=(String)request.getAttribute("lienRetourFormulaire");
%>
 
<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Les erreurs suivantes se sont produites</h2>
    <ul>
        <%
          for(int i=0;i<erreurs.size();i++){
            out.println("<li>" + (String) erreurs.get(i) + "</li>\n");
        }//for
      %>
    </ul>
    <br>
    <form name="frmPersonne" method="post">
      <input type="hidden" name="action" value="retourFormulaire">
    </form>
    <a href="javascript:document.frmPersonne.submit();">
      <%= lienRetourFormulaire %>
    </a>
  </body>
</html>
 

La pagina JSP recupera l'elenco degli errori dalla richiesta (riga 8) e lo visualizza utilizzando un ciclo Java (righe 19–23). La pagina mescola codice HTML e Java, il che può essere problematico se la pagina deve essere gestita da un web designer che generalmente non comprende il codice Java. Per evitare questa commistione, si utilizzano le librerie di tag per aggiungere nuove funzionalità alle pagine JSP. Con la libreria di tag JSTL (Java Standard Tag Library), la vista precedente diventa la seguente:


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>
 
<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Les erreurs suivantes se sont produites</h2>
    <ul>
            <c:forEach var="erreur" items="${erreurs}">
                <li>${erreur}</li>
            </c:forEach>
    </ul>
    <br>
    <form name="frmPersonne" method="post">
      <input type="hidden" name="action" value="retourFormulaire">
    </form>
    <a href="javascript:document.frmPersonne.submit();">
      ${lienRetourFormulaire}
    </a>
  </body>
</html>

Il tag (riga 4)

<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>

indica l'uso di una libreria di tag definita nel file [/WEB-INF/c.tld]. Questi tag saranno utilizzati nel codice della pagina, preceduti dalla lettera c (prefix="c"). È possibile utilizzare qualsiasi prefisso a propria scelta. In questo caso, c sta per [core]. I prefissi consentono di utilizzare librerie di tag che potrebbero avere nomi identici per determinati tag. L'uso di un prefisso risolve qualsiasi ambiguità. La nuova pagina non contiene più codice Java nei due punti in cui era presente in precedenza:

  • recupero del modello di pagina [errors, returnFormLink] (sezione rimossa)
  • visualizzazione dell'elenco degli errori (righe 13–15)

Il ciclo di visualizzazione degli errori è stato sostituito dal seguente codice:


            <c:forEach var="erreur" items="${erreurs}">
                <li>${erreur}</li>
            </c:forEach>
  • Il tag <forEach> viene utilizzato per definire un ciclo
  • La notazione ${variable} viene utilizzata per visualizzare il valore di una variabile

Il tag <forEach> presenta qui due attributi:

  • items="${errors}" specifica la collezione di oggetti su cui eseguire l'iterazione. In questo caso, la collezione è l'oggetto errors. Dove si trova? La pagina JSP cerca un attributo denominato "errors" in modo progressivo e nel seguente ordine:
    • l'oggetto [request], che rappresenta la richiesta inviata dal controller: request.getAttribute("errors")
    • l'oggetto [session], che rappresenta la sessione del client: session.getAttribute("errors")
    • l'oggetto [application], che rappresenta il contesto dell'applicazione web: application.getAttribute("errors")

La collezione indicata dall'attributo items** può assumere varie forme: array, ArrayList, oggetto che implementa l'interfaccia *List*, ecc.

  • var="error" viene utilizzato per denominare l'elemento corrente della collezione in fase di elaborazione. Il ciclo <forEach> verrà eseguito in successione per ciascun elemento della collezione items. All'interno del ciclo, l'elemento della collezione in fase di elaborazione verrà quindi indicato qui come error.

La sintassi ${error} inserisce il valore della variabile error nel testo. Questa variabile non è necessariamente una stringa. JSTL utilizza il metodo error.toString() per inserire il valore della variabile error. Invece della sintassi ${error}, è possibile utilizzare anche il tag <c:out value="${error}"/>.

Tornando al nostro esempio di visualizzazione degli errori:

  • il controller inserirà un ArrayList di messaggi di errore, ovvero un ArrayList di oggetti String, nella richiesta inviata alla pagina JSP: request.setAttribute("errors", errors), dove errors è l'ArrayList;
  • grazie all'attributo items="${errors}", la pagina JSP cercherà un attributo denominato errors, in successione nella richiesta, nella sessione e nell'applicazione. Lo troverà nella richiesta: request.getAttribute("errors") restituirà l'ArrayList inserito nella richiesta dal controller;
  • La variabile error dell'attributo var="error" farà quindi riferimento all'elemento corrente dell'ArrayList, che è un oggetto String. Il metodo error.toString() inserirà il valore di questa String — in questo caso, un messaggio di errore — nell'output HTML della pagina.

Gli oggetti nella collezione elaborata dal tag <forEach> possono essere più complessi di semplici stringhe. Prendiamo l'esempio di una pagina JSP che visualizza un elenco di articoli:

1
2
3
4
5
6
7
            <c:forEach var="article" items="${listarticles}">
                <tr>
                    <td><c:out value="${article.nom}"/></td>
                    <td><c:out value="${article.prix}"/></td>
                    <td><a href="<c:url value="?action=infos&id=${article.id}"/>">Infos</a></td>
                </tr>
     </c:forEach>

dove [listarticles] è un ArrayList di oggetti di tipo [Article], che supponiamo essere un JavaBean con i campi [id, name, price, currentStock, minimumStock], ciascuno dei quali ha i propri metodi get e set. L'oggetto [listarticles] è stato inserito nella richiesta dal controller. La pagina JSP precedente lo recupera dall'attributo items del tag forEach. L'oggetto articolo corrente (var="article") si riferisce quindi a un oggetto di tipo [Article]. Consideriamo il tag alla riga 3:

<c:out value="${article.nom}"/>

Cosa significa ${article.nom}? In realtà, diverse cose a seconda della natura dell'oggetto article. Per ottenere il valore di article.nom, la pagina JSP proverà due cose:

  1. article.getNom() - nota l'ortografia getNom per recuperare il campo nome (standard JavaBean)
  2. article.get("name")

L'oggetto [article] può quindi essere un bean con un campo "name" o un dizionario con una chiave "name".

Non ci sono limiti alla profondità dell'oggetto in fase di elaborazione. Pertanto, il tag

<c:out value="${individu.enfants[1].nom}"/>

consente di elaborare un oggetto [individu] del seguente tipo:

class Individu{
    private String nom;
    private String prénom;
    private Individu[] enfants;
    // méthodes de la norme Javabean
    public String getNom(){ return nom;}
    public String getPrénom(){ return prénom;}
    public Individu getEnfants(int i){ return enfants[i];}
}

Per ottenere il valore di ${person.children[1].lastName}, la pagina JSP proverà vari metodi, tra cui questo, che avrà esito positivo:

person.getChildren(1).getLastName() dove person si riferisce a un oggetto di tipo Person.

8.0.2. Installazione ed esplorazione della libreria JSTL

Le spiegazioni fornite sopra sono sufficienti per l'applicazione che ci interessa, ma la libreria di tag JSTL offre altri tag oltre a quelli presentati. Per esplorarli, è possibile eseguire un tutorial incluso nel pacchetto della libreria.

Utilizzeremo l'implementazione JSTL 1.1 del progetto [Jakarta Taglibs] disponibile all'URL [http://jakarta.apache.org/taglibs/] (maggio 2006):

Il file ZIP scaricato contiene quanto segue:

Image

I due file con estensione .war sono archivi di applicazioni web:

  • standard-doc: documentazione sui tag JSTL
  • standard-examples: esempi di utilizzo dei tag

Distribuiremo questa applicazione all'interno di Tomcat. Avviamo Tomcat utilizzando l'opzione appropriata nel menu [Start], quindi inseriamo l'URL [http://localhost:8080] e seguiamo il link [Tomcat Manager]:

Image

Viene quindi visualizzata una pagina di autenticazione. Effettuiamo l'accesso come manager/manager o admin/admin, come illustrato nella sezione 2.3.3.

Image

Viene visualizzata una pagina che elenca le applicazioni attualmente distribuite in Tomcat:

Image

È possibile aggiungere una nuova applicazione utilizzando i moduli nella parte inferiore della pagina:

Image

Utilizziamo il pulsante [Sfoglia] per selezionare un file .war da distribuire.

Image

Lo screenshot non lo mostra, ma abbiamo selezionato il file [standard-examples.war] dalla distribuzione JSTL scaricata. Il pulsante [Deploy] salva e distribuisce questa applicazione all'interno di Tomcat.

Image

L'applicazione [/standard-examples] è stata distribuita con successo. La avviamo:

Image

Si invitano i lettori a seguire i vari link forniti in questa pagina per trovare esempi su come utilizzare i tag JSTL.

L'applicazione [standard-doc] può essere distribuita allo stesso modo dal file [standard-doc.war]. Fornisce accesso a informazioni piuttosto tecniche sulla libreria JSTL. È di minore interesse per i principianti.

8.0.3. Utilizzo di JSTL in un'applicazione Web

Negli esempi forniti con la libreria JSTL 1.2, le pagine JSP iniziano con il seguente tag:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

Abbiamo già incontrato questo tag nella Sezione 8.1.1 e ne abbiamo fornito una breve spiegazione:

  • [uri]: URI (Uniform Resource Identifier) in cui si trovano le definizioni dei tag utilizzati nella pagina. Questo URI verrà utilizzato dal server web quando la pagina JSP viene tradotta in codice Java per diventare un servlet. Viene utilizzato anche dagli strumenti di sviluppo di pagine web per verificare la sintassi corretta dei tag utilizzati nella pagina o per fornire suggerimenti di completamento automatico. Quando si inizia a digitare un tag, uno strumento che conosce la libreria può suggerire all'utente i possibili attributi per quel tag.
  • [prefisso]: prefisso che identifica questi tag nella pagina

L'URI [http://java.sun.com/jsp/jstl/core] non può essere utilizzato se non si è connessi a Internet. In questo caso, è possibile collocare il file di definizione dei tag localmente. Diversi file di questo tipo sono forniti con la distribuzione JSTL 1.2 nella cartella [tld] (Tag Language Definition):

Image

JSTL è in realtà una raccolta di librerie di tag. Useremo solo la libreria [c.tld], nota come libreria "core". Collocheremo il file [c.tld] menzionato sopra nella cartella [WEB-INF] delle nostre applicazioni:

Image

e includeremo il seguente tag nelle nostre pagine JSP per dichiarare l'uso della libreria "core":

<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>

Sebbene l'uso delle librerie di tag ci consenta di evitare di inserire codice Java nelle pagine JSP, questi tag vengono ovviamente tradotti in codice Java quando la pagina JSP viene compilata in un servlet Java. Essi utilizzano classi definite in due file JAR [jstl.jar, standard.jar] presenti nella cartella [lib] della distribuzione JSTL:

Image

Questi due file JAR vengono inseriti nella cartella [WEB-INF/lib] delle nostre applicazioni:

Image

Ora disponiamo delle nozioni di base per affrontare la prossima versione della nostra applicazione di esempio.