La caratteristica principale della programmazione di Java è l’uso delle classi e degli oggetti, esattamente come nei file di una classe, all’interno di un file jsp è possibile ed usare usare classi se importate ovviamente metatag:
<%@ page import="it.alnao.manuali.java.NomeClasse"%>
dopo l’import è possibile usare la classe nelle scriptlet, per esempio un metodo statico è richiamabile con:
<% NomeClasse.NomeMetodoStatico(); %>
Per JSP Tags si intendono elementi java utilizzabili nel codice delle pagine jsp, distribuiti dentro a delle librerie particolari dette TagLib che definiscono la “firma” del tag e anche la propria implementazione, l’uso di questi permette di separare il codice “client” da quello “server” con lo scopo di evitare di scrivere codice Java puro nelle pagine jsp e di superare i limiti della programmazione XHTML. Tutti i Custom tag hanno questa sintassi:
<prefix:tag attr1="value" ... attrN="value" />
oppure:
<prefix:tag attr1="value" ... attrN="value" >Body</prefix:tag>
esattamente come un tag di HTML o come i tag standard JSP. Per usare un custom tag dentro ad una jsp bisogna importgare la TagLib e poi definirla, all’interno di ogni TagLib è presente un file TLD che rappresenta le firme dei tag e definisce quali classi java implementano quel tag, è fondamentale conscere il TLD di una taglib.
Il più semplice tag è quello messo a disposizione proprio dal J2EE, nello specifico il tag jsp permette di eseguire operazioni basiche su request e response, per esempio se si vuole usare un oggetto che è già presente in request o in sessione si può ridurre il codice scritto usando il tag usebean, per esempio:
<jsp:useBean id="NomeBean" scope="session" class="it.alnao.manuali.java.NomeClasse"/>
questo tag prende dalla sessione l’oggetto NomeVariabile, lo casta al tipo indicato e crea nella pagina una variabile di nome NomeVariabile con quel valore, cioè questo tag sostituisce l’istruzione
<% NomeClasse var=(NomeClasse) request.getSession().getAttribute("NomeBean"); %>
molto usato in quei progetti dove vengono usate le scriplet e non linguaggi più evoluti come le jstl o i tag Struts, analogamente al tag useBean esistono i tag setProperty e getProperty che servono a valorizzare e leggere proprietà di un oggetto bean, la sintassi è
<jsp:setProperty name="NomeBean" property="NomeProp" param="Valore" /> <jsp:getProperty name="NomeBean" property="NomeProp">
Da notare che per usare questi tag non serve importare nessuna libreria jar perchè sono tag “standard” java e vengono riconosciuti automaticamente dal WebServer, è presente anche un tag per importare altre pagine jsp in maniera dinamica:
<jsp:import
alternativa al bruttissimo:
<%@ include file="filedaincludere.jsp" %>
ma è corretto nominarlo ed evitarlo se possibile.
Per Custom tags si intendoo tag sviluppati all’interno del progetto o comunque non rilasciati ufficialmente dalla libreria J2EE, all’interno delle applicazioni JEE si hanno a disposizione più modi di creare un custom-tag, uno dei metodi più classici è quello di usare una classe java e un TLD per la descrizione del tag detti TLD acronimo di Tag Library Descriptor. Il primo passo per creare un TLD-TAG è quello di creare un file TLD nella giusta cartella del progetto WebContent/WEB-INF/tld/nome.tld
, ricordandosi che ad un tld non corrisponde un solo tag ma corrisponde una libreria che può comprendere anche più tag, una documentazione completa dei file TLD può essere trovata nella documentazione ufficiale , lo scheletro base di questo tipo di file è:
<?xml version="1.0" encoding="UTF-8"?> <taglib version="2.0" 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-jsptaglibrary_2_0.xsd"> <description>Alnao tag library</description> <tlib-version>1.0</tlib-version> <short-name>alnao</short-name> <tag> <name>TagCommentoSenzaParametri</name> <tag-class>it.alnao.prova.tags.TagCommentoSenzaParametri</tag-class> <body-content>JSP</body-content> </tag> <tag> <description>Importo</description> <name>Importo</name> <tag-class>it.alnao.prova.tags.ImportoTag</tag-class> <body-content>JSP</body-content> <attribute> <name>positiveStyle</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>negativeStyle</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
in questo file viene definita una libreria assegnandogli anche uno short-name e un elenco di tag dove, per ogni elemento, è definito il nome, la classe e gli attributi se presenti. Poi serve implementare la classe TagCommentoSenzaParametri che deve espandere la classe TagSupport, per esempio un tag java che scrive un commento in pagina è
package it.alnao.prova.tags; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.tagext.TagSupport; public class TagCommentoSenzaParametri extends TagSupport { private static final long serialVersionUID = 1L; public int doStartTag() throws JspException { String s="\n\n<!-- prova tag AlNao.it -->\n\n"; try { JspWriter out = pageContext.getOut(); out.println(s); } catch (Exception e) { e.printStackTrace(); } return SKIP_BODY; } public int doEndTag() throws JspException { return EVAL_PAGE; } }
mentre un esempio di tag per la visualizzazione di importi è:
package it.alnao.prova.tags; import java.io.IOException; import java.math.BigDecimal; import java.util.Locale; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.BodyTagSupport; public class ImportoTag extends BodyTagSupport { private static final long serialVersionUID=1L; private String positiveStyle = null; private String negativeStyle = null; private String bodyTag = null; public int doStartTag() throws JspException { return EVAL_BODY_BUFFERED; } public int doAfterBody() throws JspException { bodyTag = getBodyContent().getString().trim(); if (bodyTag != null) { Number decimal; DecimalFormat df = new DecimalFormat(); decimal = df.parse(bodyTag); if (decimal != null) { if (decimal.doubleValue() > 0) { //positivo bodyTag = "<span class=\"" + getPositiveStyle() + "\">"; } else { if (decimal.doubleValue() < 0) { //negativo bodyTag = "<span class=\"" + getNegativeStyle() + "\">"; } } else { //zero bodyTag = "<span class=\"defaultClass\">" ;//+ bodyTag } } else { //non è un numero bodyTag = "<span>"; } return (SKIP_BODY); } public int doEndTag() throws JspException { bodyTag = bodyTag + "</span>"; try { this.pageContext.getOut().print(this.bodyTag); } catch (IOException ioe) { throw new JspException(ioe); } return EVAL_PAGE; } ... metodi get e set delle proprietà ... }
All’interno delle pagine jsp, per poter usare questi tag è necessario importarli con una scriptlet:
<%@ taglib uri="/WEB-INF/tld/nome.tld" prefix="nomeTLD" %>
e poi è necessario usare il prefisso definito per chiamare i singoli tag, per esempio:
<nomeTLD:TagCommentoSenzaParametri /> <nomeTLD:Importo positiveStyle="classeCCS1" negativeStyle="classeCCS2">-12.12</nomeTLD:Importo>
Un metodo più semplice per creare TLD-TAG è usare classi java pure e, grazie alla tecnica dell’ereditarietà di Java, utilizzare classi già esistenti per evitare di scrivere codice già presente in altri tag, per esempio è possibile creare un tag condizionale “if” personalizzato che abbia due parametri in input, se sono uguali il corpo del tag verrà visualizzato in pagina, altrimenti il codice verrà saltato, riportando il codice di esempio di questo tag condizionale:
import javax.servlet.jsp.JspTagException; import javax.servlet.jsp.jstl.core.ConditionalTagSupport; public class IfTag extends ConditionalTagSupport { private String value1 = null; private String value2 = null; public IfTag() { super(); } protected boolean condition() throws JspTagException { if (value1==null || value2==null) throw new JspTagException ("Parametri nulli"); return value1.equals(value2); } }
dopo aver definito il file tld corrispettivo, in una qualsiasi pagina jsp poi basta usare il tag così:
<MieiTag:IfTag value1="uno" value2="due"> <% //questo codice non viene eseguito perchè "uno" è diverso da "due" %> </MieiTag:IfTag> <MieiTag:IfTag value1="tre" value2="tre"> <% //questo codice viene eseguito perchè le stringhe sono uguali %> Viene mostrato questo messaggio perchè "tre"=="tre" </MieiTag:IfTag>
Allo stesso modo è possibile scrivere un tag “else” che estende la classe “if” in questo modo ma che nega il valore del metodo condition:
public class ElseTag extends IfTag{ protected boolean condition() throws JspTagException { return ! super(); } }
nota: la classe ConditionalTagSupport si trova nella libreria jstl che deve essere importata nel file di configurazione di Maven.
Creare un custom-tag con una classe java è una tecnica molto elegante ma può risultare complicata se si deve scrivere un TAG che comprende molto codice client all’interno perché, per scrivere codice HTML dalla classe, si usa il metodo out che può risultato non semplicissimo da usare e il risultato rischia di diventare una classe molto lunga con molte stringhe costanti all’interno del codice. Esiste una alternativa alla tecnica dei Java-TLD: usare un file jsp dedicato al posto di una classe Java. Prima di tutto bisogna sempre definire un TLD e il riferimento al tag senza però nessun parametro anche se previsti, per esempio:
<tag-file> <name>tag_esempio</name> <path>/WEB-INF/tags/esempio.tag</path> </tag-file>
poi è necessario creare il file che per convenzione ha estensione tag anche se in realtà è un file jsp, questo file deve sempre iniziare con il meta-tag specifico previsto da J2EE:
<%@ tag %>
e al suo interno deve essere presente l’elenco degli attributi, cioè i parametri del tag, per esempio:
<%@ attribute name="oggetto" required="true" rtexprvalue="true" description="." %>
e dopo si inserisce il codice HTML/Java del tag come se fosse un file jsp, per esempio
<DIV class="classeDiv"> L'oggetto ha nome <%=request.getParameter("oggetto")%> </DIV>
Per richiamare il tag da qualsiasi pagina JSP basta invocarlo richiamando il tag definito nel TLD:
<tagLib:tag_esempio oggetto="valore" />
Scegliere tra con una classe Java o con un file jsp è una questione di gusti, tipicamente si usano i file jsp quando il codice HTML è tanto e il codice Java è poco, viceversa si usano le classi quando il codice Java è molto complicato oppure se si deve definire un tag che estende un altro tag. La documentazione ufficiale è sempre il punto di riferimento per tutti gli sviluppatori.