Utilizzare le TAGLIB con il JSP


Home Page | Commenti | Articoli | Faq | Documenti | Ricerca | Archivio | Storie dalla Sala Macchine | Contribuire | Imposta lingua:en it | Login/Register


Le Tag Libraries consentono di semplificare lo sviluppo di siti attivi e di distribuire il codice in maniera semplice da utilizzare e riutilizzare.

Non so se voi siete il tipo che crea i propri siti dalla base alla cima o se (come capita a volte a me) vi trovate impegolati nella costruzione del sito con qualcuno che si occupa della parte grafica.

In questo caso spero che il vostro "grafico" sappia anche che cosa e' un tag HTML e come funzionano le cose, in caso contrario (come capita a me) sono dolori...

Questo perche' il grafico sa' tutto quello che c'e' da sapere su come si fanno gli effetti di "shading" con Photoshop magari, ma non capisce perche' poi il sito si carica in 45 minuti.

In molti casi si vorrebbe che "lui" si occupasse della parte di definizione del "layout" del sito, mentre noi ci preoccupiamo di costruire il database dei contenuti e tutte queste amenita' che con il Web stesso c'entrano poco o niente. Purtroppo poi l'unione del nostro codice con la sua grafica e' sempre un pianto greco...

Sarebbe moooolto bello se si potesse definire il proprio codice in maniera tale che il grafico potesse prendere i singoli "pezzi" ed "incollarli" sulla pagina esattamente come sono incollati ed aggiustati gli elementi grafici.

E la cosa non e' poi tanto difficile, l'unica cosa che occorre fare e' definire i "blocchi" di codice nella stessa maniera con cui sono definiti i tag HTML.

Questo e' lo scopo delle Tag Libraries.

Per poter definire ed usare le Tag Lib occorre un Web Server che supporti il JSP e le Servlet, come minimo che sia coerente con le specifiche JSP 1.0.

Vi sono svariati server che servono (gioco di parole involontario) allo scopo, i principali sono :

Inoltre sara' necessario installare anche un JDK (Java Developer Kit). Trovate il JDK direttamente sul sito della Sun (http://java.sun.com).

Per definire una tag library occorre definire due cose:

  1. Un file TLD (Tag Lib Definition) che specifica i singoli Tag ed a quale "classe" corrispondono
  2. Le classi che effettivamente gestiscono i tag

In parole povere, il file TLD (e' un file XML), specifica i singoli tag, quali sono i loro parametri (se ne hanno), quale e' il "body" (se esiste) e quale classe Java si occupa di gestirlo, le singole classi poi devono essere sviluppate per gestirsi ogni tag.

Una singola Tag Lib puo' contenere centinaia di tag o uno solo.

Un esempio (semplice) di file TLD e' il seguente:


<?xml version="1.0" encoding="ISO-8859-1" standalone="no" ?>
<!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>mytaglib</shortname>
  <uri>taglib</uri>

  <tag>
    <name>test</name>
    <tagclass>test</tagclass>
    <bodycontent>emtpy</bodycontent>
    <attribute>
      <name>first</name>
      <required>true</required>
    </attribute>
  </tag>
</taglib>

Questo file stabilisce che la "versione" della libreria e' la 1.0 (tlibversion), il nome della libreria e' mytaglib (attributo shortname), ed i file .class si trovano nella directory taglib (attributo uri).

Viene definito un solo tag denominato TEST (che fantasia he?), che non ha "corpo" (bodycontent=empty), ha un solo "attributo" denominato first che e' obbligatorio, e viene "gestito" dalla classe denominata test.

Una volta definito il file TLD, possiamo includerlo nelle nostre pagine JSP mettendo in testa al file la definizione seguente:


<%@ taglib uri="taglib.tld" prefix="mtl" %>

Il prefix viene usato per distinguere i tag di una libreria dall'altra, in questo modo e' possibile avere lo stesso tag in diverse librerie senza pero' confonderle tra di loro.

Una volta inserito il richiamo della libreria, possiamo usare i tag con:


<mtl:test first="first par">

Questo richiama il tag test della libreria definita dal prefisso mtl, passandogli come parametro first il testo indicato.

Per definire un tag occorre scrivere una apposita classe Java che estenda TagSupport (questo per i tag "semplici", per tag piu' complessi sono disponibili classi-base piu' complete).

La classe deve implementare i metodi: doStartTag() e doEndTag().

Se il tag non ha nessun "body", la StartTag deve ritornare come valore SKIP_BODY, altrimenti si generera' un errore di runtime.

Se abbiamo definito uno o piu' parametri nel tag, per ogni parametro occorrera' definire la coppia di metodi setparamname e getparamname, per permettere di impostare e recuperare il valore dei vari parametri.

Una volta definita la classe il nostro tag e' pronto a funzionare.

Questo e' il codice per il nostro tag "test":


import javax.servlet.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;

public class taglib
  extends TagSupport
{
  private String first;
  
  public int doStartTag() 
    throws JspException
  {
    try
    {
      pageContext.getOut().println("Questo e' il tag!<br>");
      pageContext.getOut().println( first );
    }
    catch( Exception e )
    {
      throw new JspException( "taglib:" + e.getMessage() );
    }

    return SKIP_BODY;
  }

  public int doEndTag()
  {
    return EVAL_PAGE;
  }

  public void setfirst( String first )
  {
    this.first = first;
  }

  public String getfirst()
  {
    return first;
  }
}

Il tag si limita a visualizzare la scritta "Questo e' il tag!" seguito dal valore indicato come parametro "first".

Il valore di EVAL_PAGE ritornato dalla EndTag fa' si' che il resto della pagina venga elaborata in modo "normale".

Il tag seguente e' un po' piu' complesso, e serve anche a dare un'occhiata alle effettive potenzialita' di questo arnese.

Il Tag consente di visualizzare una tabella di valori estratti da un database.

Il tag richiede i seguenti parametri:

Il TLD che definisce il nostro TAG e' il seguente:


<?xml version="1.0" encoding="ISO-8859-1" standalone="no" ?>
<!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>mytaglib</shortname>
  <uri>taglib</uri>

  <tag>
    <name>query</name>
    <tagclass>query</tagclass>
    <bodycontent>emtpy</bodycontent>
    <attribute>
      <name>sql</name>
      <required>true</required>
    </attribute>
    <attribute>
      <name>dsn</name>
      <required>true</required>
    </attribute>
    <attribute>
      <name>user</name>
      <required>true</required>
    </attribute>
    <attribute>
      <name>password</name>
      <required>true</required>
    </attribute>
    <attribute>
      <name>fields</name>
      <required>true</required>
    </attribute>
  </tag>
</taglib>

Mentre il codice che definisce il tag e' il seguente:


import javax.servlet.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.sql.*;
import java.util.StringTokenizer;

public class query
  extends TagSupport
{
  /* SQL String used to query the database */
  private String sql;

  /* user name */
  private String user;

  /* password */
  private String password;

  /* DSN */
  private String dsn;

  /* fields list */
  private String fields;

  /* start the tag and perform the work */
  public int doStartTag() 
    throws JspException
  {
    /* used to parse the fields list */
    StringTokenizer t;
    String connString;
    int fieldnum;

    /* try to connect to the database */
    try
    {

      /* load the database driver and open the connection <b>(1)</b>*/
      Connection conn;
      Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");

      /* build the connection string <b>(2)</b>*/
      connString = "jdbc:odbc:" + dsn;
      connString += ";UID=" + user + ";PWD=" + password;

      conn = DriverManager.getConnection(connString);

      /* build the statement and execute the query <b>(3)</b>*/
      Statement st = conn.createStatement();
      ResultSet rs = st.executeQuery( sql );

      /* loop over the data <b>(4)</b>*/
      pageContext.getOut().println( "<table>" );
      while( rs.next() )
      {
        /* display fields */
        pageContext.getOut().println( "<tr>" );

        /* parse the fields list <b>(5)</b>*/
        t = new StringTokenizer( fields, "," );

        while( t.hasMoreTokens() )
        {
        	/* display a single field <b>(6)</b> */
          pageContext.getOut().println( "<td>" );
          pageContext.getOut().println( rs.getString( t.nextToken()));
          pageContext.getOut().println( "</td>" );
        }
        
        /* close the line <b>(7)</b>*/
        pageContext.getOut().println( "</tr>" );
      }
      pageContext.getOut().println( "</table>" );

      /* close the recordset <b>(8)</b>*/
      rs.close();
      st.close();
      conn.close();
    }
    catch( Exception e )
    {
      /* any exception */
      throw new JspException( "query:" + e.getMessage() );
    }

    return SKIP_BODY;
  }

  /* close the tag */
  public int doEndTag()
  {
    return EVAL_PAGE;
  }

  /* set/get the fields list */
  public void setfields( String fields )
  {
    this.fields = fields;
  }
  public String getfields()
  {
    return fields;
  }

  /* set/get the SQL string */
  public void setsql( String sql )
  {
    this.sql = sql;
  }
  public String getsql()
  {
    return sql;
  }

  /* set/get the username */  
  public void setuser( String user )
  {
    this.user = user;
  }
  public String getuser()
  {
    return user;
  }

  /* set/get the password */  
  public void setpassword( String password )
  {
    this.password = password;
  }
  public String getpassword()
  {
    return password;
  }

  /* set/get the dsn */
  public void setdsn( String dsn )
  {
    this.dsn = dsn;
  }
  public String getdsn()
  {
    return dsn;
  }
}

L'unica parte complessa del codice e' la doStartTag, che effettua anche tutto il lavoro:
in (1) viene caricato il driver per il database, viene poi definita in (2) la stringa di connessione mettendo insieme i parametri che sono stati definiti nel tag stesso, il recordset viene aperto in (3) e quindi viene letto in sequenza un record alla volta nel seguente ciclo ((4)).
Per ogni record la sequenza dei campi da visualizzare viene letta in (5), ed i singoli campi sono mostrati a video in (6), al termine del record, la linea di tabella viene chiusa in (7). Al termine del recordset (8) viene chiusa l'intero recordset e la connesione.

Per utilizzare il nostro tag e' sufficiente mettere in una pagina JSP una cosa come la seguente:


<%@ taglib uri="taglib.tld" prefix="mtl" %>
<html>
<head>
<title>TagLib Test</title>
</head>

<h1>Tabella</h1>
<mtl:query
  sql="SELECT FirstName,LastName FROM PERSONS"
  dsn="SOFT"
  user="TUSS"
  password="TUSS"
  fields="FirstName,LastName"
/>
</body>
</html>

Nota: il tag e' stato messo su piu' righe solo per migliorarne la leggibilita'.

Il tag qui' presentato e' semplicemente per mostrare cosa puo' essere ottenuto usando un po' di codice, l'utilita' della cosa e' che una volta definita la libreria, non c'e' piu' bisogno di preoccuparsi di connessioni, driver o cose cosi'. Anche il nostro grafico che non sa' niente di computer e' in grado di usare un Tag HTML definito in questo modo (basta che capisca cosa cavolo e' la password). Quindi sposteremo il problema sulla definizione della query SQL e non su tutto il resto, inoltre e' molto piu' semplice per lui spostare tutta la nostra tabella da una pagina all'altra senza perdersi dei "pezzi" per la strada.

JSP Tag Library Tutorial
Java Servlet specification
JSP Specification
Java Bean Component Architecture


I commenti sono aggiunti quando e soprattutto se ho il tempo di guardarli e dopo aver eliminato le cagate, spam, tentativi di phishing et similia. Quindi non trattenete il respiro.

4 messaggi this document does not accept new posts

Ferdinando

Ferdinando Di Ferdinando postato il 31/03/2008 12:22

Grazie, l'articolo mi è stato molto utile per capire quello che sto usando per il mio lavoro.

filsysadmin

filsysadmin Di filsysadmin postato il 17/12/2008 15:19

Bell'articolo D il problema nasce dal fatto (per ciò che riguarda la mia esperienza) e che il Grafico si occupa di fare i disegni(non solo) ma non sa una cippa del HTML.
Avevo sviluppato un componente webdav in vb che realizzava una treeview (upgradando dove doveva ciò che serviva),il problema era solo che si doveva definire il tipo di file da upgradare (c'era un comodo combobox) e che dovevi salvare il file come si salva un qualsiasi file sul pc.
Il problema è che lui non sa salvare un file sul pc.
Grafico == pseudodisegnatore-che-a-volte-accende-il-pc.

maxxfi

Finalmente... Di maxxfi postato il 14/09/2009 13:04

Grazie D! Finalmente con parole semplici ho capito che diavolo e' Tomcat :\) -- maxxfi

Cinghiale

Bene Di Cinghiale postato il 07/05/2010 17:03

Per articoli così chiari e comprensibili è dovere fare i Complimenti all'autore. -- Cinghiale

Precedente Successivo

Davide Bianchi, lavora come Unix/Linux System Administrator presso una societa' di Hosting in Olanda.

Volete contribuire? Leggete come!.
 
 

Il presente sito e' frutto del sudore della mia fronte (e delle mie dita), se siete interessati a ripubblicare uno degli articoli, documenti o qualunque altra cosa presente in questo sito per cortesia datemene comunicazione (o all'autore dell'articolo se non sono io), cosi' il giorno che faccio delle aggiunte potro' avvisarvi e magari mandarvi il testo aggiornato.


Questo sito era composto con VIM, ora e' composto con VIM ed il famosissimo CMS FdT.

Questo sito non e' ottimizzato per la visione con nessun browser particolare, ne' richiede l'uso di font particolari o risoluzioni speciali. Siete liberi di vederlo come vi pare e piace, o come disse qualcuno: "Finalmente uno dei POCHI siti che ancora funzionano con IE5 dentro Windows 3.1".

Web Interoperability Pleadge Support This Project
Powered By Gojira