CERCA SITEMAP FEED RSS 1280
Ultimo aggiornamento: 30 Agosto 2009

Facelets

Quando è stata introdotta la tecnologia JavaServer Faces si pensava di utilizzarla congiuntamente alle JavaServer Pages nella creazione delle pagine di una web application.
Come è noto però, il ciclo di vita JavaServer Faces è composto da diverse fasi e a differenza di JSP che processa gli elementi di una pagina nell’ordine in cui questi appaiono, JSF organizza i componenti di una pagina in una complessa struttura ad albero.
Tali differenze pongono in essere una serie di incompatibilità legate al fatto che i componenti gestiti da JSP vengono visualizzati in ordine di apparizione all’interno della pagina mentre quelli JSF secondo quanto definito dalla fase di Render Response.
Facelets nasce per sostituire JSP nella creazione delle pagine, superando tali incompatibilità e fornendo i seguenti vantaggi:
  • indipendenza dal web container
  • compatibilità con qualsiasi versione JSF
  • tempi di compilazione più veloci
  • supporto per il templating
  • supporto di Expression Language
Per utilizzare Facelets all’interno di una web application è necessario configurare il file web.xml specificando il suffisso delle pagine che utilizzeranno Facelets (per convenzione l’estensione delle pagine che usano Facelets è xhtml):
<web-app>
  <context-param>
    <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
    <param-value>.xhtml</param-value>
  </context-param>
</web-app>
Facelets inoltre sostituisce il ViewHandler JSF con la classe FaceletViewHandler del package com.sun.facelets che va indicata all’interno del file faces-config.xml:
<faces-config>
  <application>
    <view-handler>
      com.sun.facelets.FaceletViewHandler
    </view-handler>
  </application>
</faces-config>

Librerie di tag

Facelets richiede che la pagina XML sia valida, definendo i namespace è possibile inoltre specificare quelle che sono le librerie di tag utilizzate all’interno della pagina.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns=”http://www.w3.org/1999/xhtml” xmlns:ui=”http://java.sun.com/jsf/facelets” xmlns:h=”http://java.sun.com/jsf/html”>
Nell’esempio precedente si utilizzano tre librerie di tag, la libreria di tag xhtml (senza prefisso), la libreria di tag Facelets con prefisso ui e la libreria di tag HTML di JSF con prefisso h.

Tag Facelets

Il tag ui:component inserisce una nuova istanza di UIComponent nell’albero dei componenti JavaServer Faces o come radice dell’albero o all’interno dell’elemento che lo contiene: ogni cosa all’esterno del tag ui:component viene ignorata.

Gli attributi di ui:component sono due:
  • id: consente di specificare un identificativo per il componente
  • binding: consente di fare riferimento alla proprietà di un backing bean dello stesso tipo
<ui:component binding="#{miobean.miocomponent}">
  ...

</ui:component>
Il tag ui:composition è usato per incapsulare contenuti che sono usati in altre pagine (templating).
Questo tag ha un attributo template che fa riferimento al path del template che sarà popolato dagli elementi contenuti all’interno di ui:composition.
Nel seguente esempio il contenuto del tag ui:composition viene utilizzato per popolare il tag ui:insert con attributo name pari a menu all’interno del template template.xhtml
<ui:composition template="template.xhtml">
  <ui:define name="dati">
    <h:panelGrid columns="2">
      <h:outputText value="Nome"/>
      <h:outputText value="#{persona.nome}"/>
      <h:outputText value="Cognome"/>
      <h:outputText value="#{persona.cognome}"/>
    </h:panelGrid>
  </ui:define>
</ui:composition>
Il tag ui:debug è molto utile per effettuare il debugging di una web application, infatti utilizzando la combinazione di tasti Ctrl+Shift+<hotkey> (dove hotkey è specificata dall’attributo hotkey) è possibile visualizzare l’albero dei componenti e le variabili di scope.
L’attributo opzionale rendered se posto a false non inserisce lo script necessario a visualizzare la finestra di debug nella pagina.
<ui:debug hotkey="g" rendered="#{miobean.debug_mode}" />
L’elemento ui:decorate è simile all’elemento ui:composition, l’unica differenza è rappresentata dal fatto che non rimuove ciò che non si trova al suo interno.
L’attributo template consente quindi di specificare il path del template che verrà popolato con il contenuto dell’ui:decorate.
<p>Questo non viene cancellato</p>
  <ui:decorate template=" template.xhtml">
    <ui:define name="nome1">
      Contenuto nome1
    </ui:define>
    <ui:define name="nome2">
      Contenuto nome2
    </ui:define>
  </ui:decorate>
<p>Questo non viene cancellato</p>
Il tag ui:define viene utilizzato all’interno degli elementi ui:composition e ui:decorate per sostituire al posto dei tag ui:insert presenti nel template (aventi lo stesso attributo name del tag ui:define) il contenuto definito al loro interno.
<ui:define name="nome1">

  Contenuto nome1

</ui:define>
Nel precedente esempio i tag ui:insert (presenti in template.xhtml) con attributo name pari a “nome1” e “nome2” saranno sostituiti dal contenuto degli elementi ui:define aventi lo stesso attributo name.
Il tag ui:fragment è simile al tag ui:component ma non elimina il contenuto al di fuori di esso.
Questo tag inserisce un UIComponent nell’albero dei componenti impostando come figli tutti gli elementi al suo interno.
Anche gli elementi al di fuori del tag saranno inseriti nell’albero ma non come figli dell’elemento rappresentato dal tag ui:fragment.
<p>Questo non viene eliminato</p>
  <ui:fragment>
    <div>
      <h:outputText value="#{miobean.valore}"/>
    </div>
  </ui:fragment>
<p>Questo non viene eliminato</p>
L’elemento ui:include viene utilizzato per includere un altro documento Facelets nella pagina: è possibile includere file che abbiano i tag ui:component e ui:composition o semplicemente frammenti di codice XML o XHTML.
<div>
  <ui:include src="#{miobean.src}"/>
</div>
Il tag ui:insert viene utilizzato per specificare in un template le parti sostituibili: ha un attributo name (al quale deve corrispondere l’attributo name del corrispondente ui:define) e può contenere altri elementi al suo interno che vengono visualizzati se il corrispondente ui:define non viene definito.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns=”http://www.w3.org/1999/xhtml” xmlns:ui="http://java.sun.com/jsf/facelets">
  <body>  
    <h1>
      <ui:insert name="titolo">
        Nessun titolo inserito
      </ui:insert>
    </h1>  
    <div>
      <ui:insert name="contento">
        Nessun contenuto definito
      </ui:insert>
    </div>
  </body>
</html>
Se l’attributo name non viene specificato l’intero contenuto dell’elemento ui:composition che fa riferimento al template sarà inserito al suo posto.
Il tag ui:param viene utilizzato per il passaggio di oggetti fra Facelets, non può contenere elementi al suo interno e ha due attributi:
  • name: fa riferimento al nome dell’oggetto
  • value: contiene un’espressione valore EL o un letterale.
Il tag ui:remove è usato per rimuovere blocchi di codice a tempo di compilazione.
<ui:remove>

  Questo sarà rimosso.
  
</ui:remove>
Infine il tag ui:repeat viene usato per iterare su una lista di oggetti ed ha due attributi:
  • value: referenzia la List di oggetti da iterare
  • var: un nome con il quale si referenzia la lista nel corpo di ui:repeat per accedere ai singoli elementi
<ul>
  <ui:repeat var="elemento" value="#{miobean.elementi}">
    <li>#{elemento.valore}</li>
  </ui:repeat>
</ul>

Creare composizioni di componenti

Facelets offre la possibilità di creare delle composizioni di componenti e di registrare tag personalizzati per richiamarli all’interno delle pagine.
Supponiamo di voler creare una combinazione di h:outputText e h:inputText che possa essere inserita in una pagina mediante il tag:
<mioprefisso:miotag label="nome" value="#{miobean.nome}" />
La prima cosa da fare è creare un file xhtml che contenga la composizione dei due elementi
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns=”http://www.w3.org/1999/xhtml” xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html">
  <ui:component>
    <h:outputLabel value="#{label}: ">
      <h:inputText value="#{value}"/>
    </h:outputLabel>
  </ui:component>
</html>
Come vediamo le espressioni EL fanno riferimento agli attributi dell’elemento personalizzato.

Quindi occorre registrare il tag nella corrispondente libreria
<!DOCTYPE facelet-taglib PUBLIC "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN" "http://java.sun.com/dtd/facelet-taglib_1_0.dtd">
<facelet-taglib>
  <namespace>http://www.giuseppesicari.it/personalizzato</namespace>
  <tag>
    <tag-name>miotag</tag-name>
    <source>miotag.xhtml</source>
  </tag>
</facelet-taglib>
Quindi occorre specificare la libreria che si sta utilizzando nel file web.xml
<context-param>
  <param-name>facelets.LIBRARIES</param-name>
  <param-value>/WEB-INF/facelets/mialibreria.taglib.xml</param-value>
</context-param>
Quindi è possibile usare il tag all’interno della pagina specificando il namespace della libreria
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns=”http://www.w3.org/1999/xhtml” xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f=”http://java.sun.com/jsf/core” xmlns:h="http://java.sun.com/jsf/html" xmlns:mioprefisso=" http://www.giuseppesicari.it/personalizzato ">
  <body>
    <f:view>
      <h:form>
        <h:panelGrid columns="1">
          <mioprefisso:miotag label="nome" value="#{miobean.nome}"/>
        </h:panelGrid>
      </h:form>
    </f:view>
  </body>
</html>