La libreria standard del framework Struts mette a disposizione alcuni tag pronti all’uso molto utili che aiutano molto quando c’è la necessità di introdurre logiche in pagina e si vuole evitare di usare le scriptlet come consigliato da tutti i manuali. La documentazione ufficiale dei tag è molto ricca di esempi e questo articolo vuole esserne un riassunto , il più semplice, come già visto nel precedente articolo, è il tag per visualizzare messaggi:
<bean:message key="app.title"/>
Tuttavia la libreria bean mette a disposizione messaggi per visualizzare oggetti e proprietà all’interno degli oggetti:
<bean:write name="employee" property="username" />
Se, nelle pagine jsp, si vogliono recuperati oggetti salvati in request dalla classe action è necessario configurare struts affinché non esegua un redirect (creando una nuova request) ma impostando a false il parametro verrà mantenuta la stessa request tra classe Action pagina jsp di destinazione:
<forward name="success" path="/success.jsp" redirect="false" />
Altri tag a disposizione sono il define per dichiarae valori
<bean:define id="displayText" value="Text to Display" /> <bean:write name="displayText" />
Un altro gruppo molto usato sono i tag logici di cui si riportano alcuni esempi:
<logic:notPresent name="logonForm"> <html:link forward="logon">Sign in here</html:link> </logic:notPresent> <logic:present name="logonForm"> <html:link forward="logoff">Sign out</html:link> </logic:present> <logic:empty name="user"> <forward name="login" /> </logic:empty /> <bean:define id="value2" name="bean2" property="value"/> <logic:equal value="<%=(String) value2 %>" name="bean1" property="value"> HIT! </logic:equal> <logic:iterate id="employee" name="employees"> <tr align="left"> <td> <bean:write name="employee" property="username" /> </td> <td> <bean:write name="employee" property="name" /> </td> <td> <bean:write name="employee" property="phone" /> </td> </tr> </logic:iterate>
In assoluto i tag più usati della libreria struts sono i tag per la gestione degli input, questi permettono di gestire i Form collegati direttamente agli ActionForm, l’esempio base già visto nel precedente articolo è la sostituzione dei classici tag HTML con i tag specifici della libreria che permetteranno a Struts di valorizzare il Bean ActionForm con i valori inseriti in pagina:
<html:form action="/login" focus="userName"> <p>Username : <html:text property="userName" /></p> <p>Password : <html:password property="password" /></p> <p><html:submit value="login" /></p> </html:form>
Si rimanda alla documentazione ufficiale per approfondimenti a riguardo visto che è una tecnica indispensabile quando si lavora in progetti di grandi dimensioni con Struts 1.
Esiste un’altra libreria molto usata chiamata JSTL (Java Standard Tag Library), con lo scopo di uniformare i tag di tutti i framework, integra i tag funzionali mancanti di Struts e alcuni vengono sostituiti da sintassi molto più semplici, grazie a questi tag si può evitare “quasi” completamente l’uso delle scriptlet all’interno delle pagine jsp. Per integrare questa libreria nel progetto basta aggiungere le dipedenze:
<dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>taglibs</groupId> <artifactId>standard</artifactId> <version>1.1.2</version> </dependency>
e nelle pagina basta importare la libreria:
<%@ taglib uri="https://java.sun.com/jsp/jstl/core" prefix="c" % %> <%@ taglib uri="https://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> <%@ taglib uri="https://java.sun.com/jsp/jstl/functions" prefix="fn" %>
I principali tag disponibili sono:
<c:out>
permette di visualizzare un dato da un bean o da un oggetti<c:import>
permette di includere in una pagina altre pagine simile a jsp:include, permette l’invio dei parametri con il sottotag<c:param>
<c:redirect>
esegue la redirect verso altre servlet<c:set>
esegue la set di un valore in una proprietà o in un oggetto<c:remove>
rimuovere una variabile o un oggetto<c:catch>
cattura eventuali exception generati al suo interno<c:if>
semplice condizione, usata anche come base per il tag catch<c:choose>
condizione articolata con usati in combinazione anche i<c:when>
and<c:otherwise>
<c:forEach>
semplice iterazione su una collezione di oggetti<c:url>
crea un link ad una servlet/action
Un semplice esempio di utilizzo di queste libreria
<c:set var = "salario" scope = "request">2200</c:set> <c:if test = "${importo > 2000}"> <p>L'importo di < c:out value = "${salary}"/> supera i 2000 €</p> </c:if>
Un occhio attento avrà notato che nella condizione della c:if
appena introdotta è presente una espressione con i caratteri ${variabile}, questa tecnica ufficiale è chiamata Expression Language (spesso abbreviato con EL), principale feature introdotta con la versione 2 di Jsp e permette di abbreviare ulteriomente il codice in pagine sostituendo alcuni tag (e alcune scriplet) con un linguaggio dedicato, questo prevede l’uso del simbolo dollaro seguito dalle istruzione in graffe, di fatto il codice
<% out.print(variabile); %> <%=variabile %> <c:out value="variabile" />
può essere sostituito con il semplice
${variabile}
questa tecnica è indispensabile quando si usano alcuni tag come le condizioni o cicli in jstl ma può essere usata in qualsiasi situazione. Deve essere attivata in pagina con il comando:
<%@ page isELIgnored="false" %>
Un esempio combinato di utilizzo di questa tecnica, per la creazione di un link con parametri:
<c:url value = "/NomeAction.do" var = "myURL"> <c:param name = "parametro1" value = "valoreUno"/> <c:param name = "parametro2" value = "valoreDue"/> </c:url> <a href="${myURL}">Link a NomeAction</a> <%--in alternativa <c:import url = "${myURL}"/> --%>
Oppure un altro esempio di ciclo su una collezioned i elementi:
<c:forEach items="${variabileElenco}" var="elmento" varStatus="status"> <p>Item posizione ${status.index} con valore ${elemento} </p> </c:forEach> <c:if test="${empty variabileElenco }"> <p>La lista vuota</p> </c:if>
Un ultimo esempio di gestione delle exception misto tra JSTL e EL:
<c:catch var ="catchException"> <% int x = 5/0;%> </c:catch> <c:if test = "${catchException != null}"> <p>L'exception lanciata è : ${catchException} Con il messaggio: ${catchException.message}</p> </c:if>
Le due librerie combinate possono semplificare molto la vita dei programmatori quando si deve eseguire formattazioni particolari, in particolare JSTP mette a disposizione la libreria:
<%@ taglib prefix = "fmt" uri = "http://java.sun.com/jsp/jstl/fmt" %>
Un elenco quasi completo di tutti i tag e le loro possibili applicazioni:
<c:set var = "balance" value = "120000.2309" /> <p>senza parametri: <fmt:formatNumber value = "${balance}" type = "currency"/> </p><p>con il massimo di interi : <fmt:formatNumber type = "number" maxIntegerDigits = "3" value = "${balance}" /> </p><p>con il massimo di decimali: <fmt:formatNumber type = "number" maxFractionDigits = "3" value = "${balance}" /> </p><p>visualizzato come percentuale: <fmt:formatNumber type = "percent" maxIntegerDigits="3" value = "${balance}" /> </p><p>percentuale con minimo di decimali: <fmt:formatNumber type = "percent" minFractionDigits = "10" value = "${balance}" /> <p><p>percentuale con il massimo di interi: <fmt:formatNumber type = "percent" maxIntegerDigits = "3" value = "${balance}" /> </p><p>esadecimale: <fmt:formatNumber type = "number" pattern = "###.###E0" value = "${balance}" /> </p><p>Con un locale particolare, per esempio in usa si usa il punto come separtore dei decimali mentre in Italia è la virgola <fmt:setLocale value = "en_US"/> <fmt:formatNumber value = "${balance}" type = "currency"/> </p> <fmt:parseNumber var = "variabile" type = "number" value = "${balance}" /> <b>Parse senza parametri: </bp> <fmt:parseNumber var = "variabile" integerOnly = "true" type = "number" value = "${balance}" /> <p>Parse solo come integer: </p> <c:set var = "now" value = "20-10-2010" /> <fmt:parseDate value = "${now}" var = "parsedEmpDate" pattern = "dd-MM-yyyy" /> <b>Parsed Date: </b> <c:set var = "now" value = "<%= new java.util.Date()%>" /> <p>Visualizza l'ora: <fmt:formatDate type = "time" value = "${now}" /></p> <p>Visualizza la data (il mese in lettere): <fmt:formatDate type = "date" value = "${now}" /></p> <p>Mostra data e ora (il mese in lettere): <fmt:formatDate type = "both" value = "${now}" /></p> <p>Mostra data e ora (il mese in numerI): <fmt:formatDate type = "both" dateStyle = "short" timeStyle = "short" value = "${now}" /></p> <p>Mostra data e ora (il mese con il nome intero) <fmt:formatDate type = "both" dateStyle = "long" timeStyle = "long" value = "${now}" /></p> <p>MOstra la data in formato personalizzato con un pattern specifico: <fmt:formatDate pattern = "yyyy-MM-dd" value = "${now}" /></p>
Infine esistono delle funzionalità specifiche importabili la libreria:
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
Le funzioni disponibili sono
fn:contains
testa se una stringa è contenuta in un’altra, per esempio:<c:set var = "theString" value = "I am a test String"/> <c:if test = "${fn:contains(theString, 'test')}"> Found test string< /c:if>
fn:containsIgnoreCase
come la precedente ma ignora maiuscole e minuscolefn:endsWith
testa se una stringa termina con una determinata stringa per esempio:<c:set var = "theString" value = "I am a test String 123"/> <c:if test = "${fn:endsWith(theString, '123')}">String ends with 123< /c:if>
fn:escapeXml
codifica gli elementi XML all’interno di una stringa come testo e non come tag HTML, per esempio:<c:set var = "string2" value = "This is second String."/> <p>string: ${fn:escapeXml(string2)}< /p> visualizzato: This is second String.
fn:indexOf
calcola la posizione di una stringa all’interno di un altrafn:join
unisce tutti gli elementi di un elenco in una stringa separati da un separatore, per esempio:<c:set var = "string1" value = "This is first String."/> <c:set var = "string2" value = "${fn:split(string1, ' ')}" /> <c:set var = "string3" value = "${fn:join(string2, '-')}" /> <p>${string3}< /p>
fn:length
calcola il numero di elementi in una lista (collection) oppure la lunghezza di una stringafn:replace
ritorna una stringa nella quale è stato sostituita tutte le occorrenze di una stringa con un’altrafn:split
divide una stringa in un array di sottostringhefn:startsWith
testa se una stringa inizia con una determinata stringafn:substring
estrae una stringa da una posizione ad un’altra (si comincia a contare da zero come in java), per esempio:<c:set var = "string1" value = "This is first String." /> <c:set var = "string2" value = "${fn:substring(string1, 5, 15)}" /> <p>is first S< /p>
fn:toLowerCase
trasforma tutti i caratteri di una stringa in minuscolofn:toUpperCase
trasforma tutti i caratteri di una stringa in maiuscolofn:trim
rimuove tutti gli spazi bianchi all’inizio e alla fine di una stringa
Inoltre è possibile definire funzioni personalizzate creando una classe java per l’implementazione della logica da eseguire nelle EL, un esempio è descritto in un mio vecchio articolo.