In questo articolo mostrerò come creare un custom tag Java da utilizzare in una pagina JSP per decorare valori numerici, semplici e percentuali, con separatori di migliaia e di decimali e per evidenziare di rosso i valori negativi.
La creazione di un custom tag prevede due differenti fasi: la sua definizione e la stesura del codice necessario.
Definire un nuovo custom tag
I custom tags sono definiti in un file XML con estensione .tld che deve essere posizionato nella cartella WEB-INF di un progetto Java WEB.
Il file .tld, abbreviazione di Tag Library Descriptor, è l'interfaccia che il Java Web Container carica per verificare la correttezza degli eventuali valori passati ai componenti ed istanziare li stessi all'occorrenza.
Il componente che sto per mostrare si chiama Quantity e prevede che li sia passato un oggetto di tipo java.math.BigDecimal. Consente anche di impostare due flag per esprimere una percentuale e per la scelta di un formato più corto che prevede un solo decimale anziché tre.
Di seguito il contenuto del descrittore del custom tag: matag-20.tld
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems,
Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/j2ee/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
<tlib-version>1.0</tlib-version>
<jsp-version>2.0</jsp-version>
<short-name>ma</short-name>
<uri>http://java.ma.it/jsp/jstl/ma</uri>
<display-name>MA Tags Library</display-name>
<description>Mirko Agrati's Tags Library</description>
<tag>
<name>quantity</name>
<tag-class>net.ma.java.tag.Quantity</tag-class>
<body-content>empty</body-content>
<description>
Decora un numero con separatori di migliaia e decimali,
esprime anche valori percentuali e evidenzia valori negativi.
</description>
<attribute>
<name>value</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>short</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>percent</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
</taglib>
Come è facilmente intuibile solo l'attributo value è necessario (e va quindi valorizzato) e tutti e tre gli attributi possono interpretare valori e riferimenti ad oggetti presenti nel contesto della pagina.
La classe Quantity
Oltre alla particolarità di estendere la classe javax.servlet.jsp.tagext.SimpleTagSupport, il componente Quantity è un semplice javabean che possiede le stesse proprietà dichiarate nella TLD e abbinate ognuna ad un metodo setter che verrà utilizzato dal container per valorizzare le proprietà dell'oggetto, come dichiarato nella pagina JSP.
La classe deve essere fornita del metodo pubblico doTag(): in questo articolo all'interno di tale metodo viene creato il codice HTML da inserire nel flusso di codice creato dalla pagina JSP.
Di seguito il codice sorgente del file Quantity.java.
package net.ma.java.tag;
import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
/**
* Decora un numero con separatori di migliaia e decimali,
* esprime anche valori percentuali e evidenzia valori negativi.
*
* @author Mirko Agrati
* @version 19/mar/2011 - v1.0
*/
public final class Quantity extends SimpleTagSupport {
private static final DecimalFormatSymbols EURO
= new DecimalFormatSymbols(Locale.ITALIAN);
private static final DecimalFormat longFormat
= new DecimalFormat("#,##0.000", EURO);
private static final DecimalFormat shortFormat
= new DecimalFormat("#,##0.0", EURO);
private BigDecimal value;
public void setValue(BigDecimal v){value = v;}
private boolean isShort;
public void setShort(String string) {
isShort = Boolean._valueOf(string).booleanValue();
}
private boolean isPercent;
public void setPercent(String string) {
isPercent = Boolean._valueOf(string).booleanValue();
}
public Quantity(){
value = null;
isShort = false;
isPercent = false;
}
@Override
public void doTag() throws JspException, IOException{
getJspContext().getOut().write(completeTag());
}
private String completeTag(){
if(value == null || value.signum() == 0)
return "-";
StringBuffer sb = new StringBuffer("<span");
if ( value.signum() < 0 )
sb.append(" style=\"color: red;\">");
else
sb.append(">");
if ( isShort )
sb.append(shortFormat.format(value));
else
sb.append(longFormat.format(value));
if ( isPercent )
sb.append("%");
sb.append("</span>");
return sb._toString();
}
}
Quando il componente sarà richiamato dalla pagina JSP, il java container ne creerà un'istanza ed eseguirà una chiamata al suo metodo doTag(), che restituirà, in questo caso, del codice HTML che sarà iniettato nel resto della pagina JSP.
Di seguito un esempio di utilizzo del componente Quantity all'interno di una JSP.
Utilizzare il tag in una JSP
Per poter accedere a tutti i componenti della libreria creata (in questo esempio vi è solo un tag) da una pagina JSP è necessario in essa fare riferimento al descrittore della libreria e dichiarare il namespace di appartenenza dei tags.
Questo lo si fa attraverso la direttiva taglib.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<%@page language="java" pageEncoding="UTF-8"
contentType="text/html; charset=UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.ma.it/jsp/jstl/ma" prefix="ma" %>
<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<meta http-equiv="Cache-Control" content="no-cache">
<meta http-equiv="Pragma" content="no-cache">
<title>Custom tag Quantity</title>
</HEAD>
<BODY>
<c:set var="pos">
<%= new java.math.BigDecimal("150000.5447") %>
</c:set>
<c:set var="neg">
<%= new java.math.BigDecimal("-150000.5447") %>
</c:set>
<p>
questo valore è positivo <ma:quantity value="${pos}" /> <br>
questo valore è negativo <ma:quantity value="${neg}" short="true"/>
</p>
</BODY>
</HTML>
In questo esempio si fa uso anche delle JSTL, ovvero le Java Standard Tag Library, un must che non dovrebbe avere bisogno di spiegazioni.
Creati un valore positivo ed uno negativo si richiede la trasformazione da parte del tag quantity.
In fine, il risultato della decorazione.
questo valore è positivo 150.000,545
questo valore è negativo -150.000,6
Solitamente in ogni mio progetto faccio un abbondante uso di custom tags e ritengo JSP2.0 una tecnologia eccezionale, molto produttiva perchè offre differenti soluzioni per ogni problema.
Alla prossima,
MA.