primefaces logoPrimeFaces è una suite open source di componenti UI avanzati progettata per integrare funzionalità Ajax all’interno di applicazioni Java Server Faces, esattamente come lo è ad esempio il più noto RichFaces. La suite Primefaces offre supporto ad Ajax, grazie ad una integrazione nativa con JQuery (e su questo ci ritorneremo più avanti). Il framework è dotato di più di 100 componenti JSF avanzati (per stuzzicarvi un po’ l’appetito potete vedere il ricco showcase).
Sono disponibili anche un kit per lo sviluppo di interfacce utente per applicazioni web mobile, PrimeMobile e un discreto insieme di temi predefiniti, come si puo’ vedere in questa themes gallery.

PrimeFaces contro tutti

Primefaces si pone in diretta concorrenza con i ben noti e già maturi RichFaces e IceFaces. Tuttavia sta suscitando un enorme interesse grazie ad alcuni punti di forza che lo rendono assai competitivo nei confronti degli altri progetti.

  • Facilità per iniziare:
    Come vedremo è sufficiente una sola libreria e zero configurazione.

  • Ajax e Jquery:
    Supporto Ajax e utilizzo non intrusivo di JavaScript, basato sulla più recente versione di JQuery.

  • Maggior numero di componenti:
    Come abbiamo detto più di 100 componenti disponibili basati su JQueryUI (HTMLEditor, Dialog, DataTable, Menu,AutoComplete,Charts e molto altro), in più con compatibilità dichiarata con altre librerie di componenti JSF.

  • Performance:
    PrimeFaces è una libreria leggera, tutte le scelte prese sono basate sul mantenere PrimeFaces il più leggero possibile.

  • Facilità d’uso:
    I Componenti in PrimeFaces sono sviluppati segondo il seguente principio di design: “Un componente UI buono dovrebbe nascondere la complessità, ma mantenere la flessibilità”.

  • Documentazione e supporto:
    Infine una ricca documentazione e pieno supporto per gli sviluppatori, grazie anche ad una attiva community

    • Quanto detto trova riscontro nel seguente articolo PrimeFaces vs RichFaces vs IceFaces.
      Come si puo vedere dal seguente risultato su Google Trends:

      primefaces trend

      ad oggi, Marzo 2012, l’interesse della comunità di sviluppatori nei confronti di questo framework è in netta crescita, tanto da aver in pochi anni raggiunto e surclassato la concorrenza, nonostante il progetto sia piuttosto giovane. Altra controprova di questo interesse per PrimeFaces è il risultato del seguente sondaggio.
      Tranquilli miei cari fan di RichFaces, non è ancora tempo di buttare tutto alle ortiche, per adesso il mercato sembra che sia ancora dominato dalle vostre amate ricche facce di JBoss, come risulta su indeed.com.
      Nel frattempo sarebbe forse il caso di cominciare a smanettare con il nuovo che avanza, che non si sa mai, che ne dite? 😉

      Getting Start

      Vediamo come creare la nostra prima applicazione con Primefaces. Per cominciare come server di riferimento utilizzeremo Tomcat (ma potete, se preferite, provare anche su JBoss o su GlassFish) e naturalmente L’IDE utilizzato sarà Eclipse versione Indigo.
      Prima di tutto ci occorrono le seguenti librerie:

      Se usate JBoss o GlassFish invece che Tomcat, allora è sufficiente solo l’ ultimo jar, cioè primefaces-3.2.jar.

      Ma procediamo con la creazione del nostro progetto. In Eclipse clicchiamo su File -> New -> Project, nel wizard per il New Project, selezioniamo Web -> Dynamic Web Project:

      new projet

      Nella fase successiva inseriamo il nome del Progetto, lo chiameremo PrimeFacesTest, selezioniamo il runtime target (abbiamo scelto Tomcat 7) e poi clicchiamo su finish.

      Dinamic Web Project

      Includiamo ora nel Build Path le librerie che abbiamo scaricato. Per farlo possiamo copiare le librerie direttamente nel folder /WebContent/WEB-INF/lib tramite drag and drop dalla cartella in cui le abbiamo scaricate, così facendo ritroveremo le librerie sotto Web App Libraries:

      Build Path

      Adesso procediamo alla creazione della seguente struttura di riferimento:

      struttura progetto

      Per prima cosa modifichiamo il web.xml in modo da includere la servlet javax.faces.webapp.FacesServlet  ed il relativo mapping, così come segue:

      [xml]
      <?xml version="1.0" encoding="UTF-8"?>
      <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns="http://java.sun.com/xml/ns/javaee"
      xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
      id="WebApp_ID" version="2.5">
      <display-name>PrimeFacestest</display-name>
      <welcome-file-list>
      <welcome-file>index.xhtml</welcome-file>
      </welcome-file-list>
      <servlet>
      <servlet-name>Faces Servlet</servlet-name>
      <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
      <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
      <servlet-name>Faces Servlet</servlet-name>
      <url-pattern>/faces/*</url-pattern>
      </servlet-mapping>
      <servlet-mapping>
      <servlet-name>Faces Servlet</servlet-name>
      <url-pattern>*.jsf</url-pattern>
      </servlet-mapping>
      <servlet-mapping>
      <servlet-name>Faces Servlet</servlet-name>
      <url-pattern>*.faces</url-pattern>
      </servlet-mapping>
      <servlet-mapping>
      <servlet-name>Faces Servlet</servlet-name>
      <url-pattern>*.xhtml</url-pattern>
      </servlet-mapping>
      </web-app>
      [/xml]

      Di seguito aggiungiamo la pagina index.xhtml dove inseriremo dei componenti PrimeFaces per testarne il funzionamento:

      [xml]
      <?xml version=’1.0′ encoding=’UTF-8′ ?>
      <!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:p="http://primefaces.org/ui">
      <h:head>
      <title>PrimeFaces Test</title>
      <style>
      .ui-widget {
      font-size: 12px !important;
      }
      </style>
      </h:head>
      <h:body>
      <h:form id="mainForm">
      <p:panel header="Match Mode" style="width: 500px;">
      <h:panelGrid columns="2" id="matchGrid">
      <h:outputLabel value="Username: " />
      <p:inputText id="user" value="#{passwordBean.username}"
      label="Username:" required="true" />
      <h:outputLabel for="pwd1" value="Password 1: *" />
      <p:password id="pwd1" value="#{passwordBean.password}"
      match="pwd2" label="Password 1"
      required="true" feedback="true" />
      <h:outputLabel for="pwd2" value="Password 2: *" />
      <p:password id="pwd2" value="#{passwordBean.password}"
      label="Password 2" required="true"
      feedback="true" />
      </h:panelGrid>
      <br />
      <p:commandButton id="saveButton"
      update="matchGrid,userOut,passOut"
      value="Save" type="submit" onclick="dlg.show();" />
      <p:dialog header="Response" position="0,0" id="dialog"
      widgetVar="dlg" modal="true" showEffect="explode"
      hideEffect="bounce" height="200" width="500"
      style="margin:50px">
      <p:messages id="messages" showDetail="true"
      autoUpdate="true" />
      <h:panelGrid columns="2">
      <h:outputLabel value="Username: " />
      <h:outputText id="userOut"
      value="#{passwordBean.username}"
      label="Username:" />
      <h:outputLabel value="Password : " />
      <h:outputText id="passOut"
      value="#{passwordBean.password}"
      label="Password" />
      </h:panelGrid>
      </p:dialog>
      </p:panel>
      </h:form>
      </h:body>
      </html>
      [/xml]
      Cui segue il corrispettivo backing bean:
      [java]
      package it.cosenonjaviste;
      import javax.faces.bean.ManagedBean;
      import javax.faces.bean.RequestScoped;
      @ManagedBean(name="passwordBean")
      @RequestScoped
      public class PasswordBean {
      private String username;
      private String password;
      public String getPassword() {
      return password;
      }
      public void setPassword(String password) {
      this.password = password;
      }
      public String getUsername() {
      return username;
      }
      public void setUsername(String username) {
      this.username = username;
      }
      }
      [/java]

      Se tutto è stato eseguito correttamente, avviamo l’applicazione sul server e proviamo a collegarci a questo indirizzo:

      http://localhost:8080/PrimefacesTest/

      Ci troveremo ora di fronte ad una form web che chiede di inserire nome utente e password, nonchè di ripetere la password per conferma.

      form primefaces

      In pratica è implementato un Cross-field validation realizzato con Primefaces e reso possibile grazie all’attributo match del componente p:password.
      Infatti la filosofia di PrimeFaces come abbiamo visto, considera cosa fondamentale la facilità d’uso dei suoi componenti, dunque con un semplice riferimento sul primo campo password, cioè pwd1, al secondo campo password match="pwd2", sarà il framework a farsi interamente carico della validazione, sollevando lo sviluppatore da ulteriori interventi.
      Se popolate adesso i campi della form e se le password inserite coincidono, cliccando su Salva, apparirà una simpatica finestra riepilogativa  (quando la chiuderete capirete perchè dico “simpatica”), altrimenti in questa vi apparirà un messaggio di errore. Notate bene che sia il campo Username che i due campi Password sono required="true", cioè sono campi obbligatori, dunque se li omettete non passeranno la validazione e sarà visualizzato per questo il relativo messaggio di errore.
      Un’ultima considerazione, nel p:commandButton è presente un attributo update, vi starete chiedendo a cosa serve?
      Orbene l’attributo update serve semplicemente per aggiornare, al termine di una richiesta Ajax, lo stato di uno più componenti, i cui id sono specificati come valore.

      JQuery

      Come già accennato all’inizio dell’articolo, la suite Primefaces offre una integrazione nativa con JQuery. Provate adesso ad aggiungere il seguente codice nella head del file index.xhtml:

      [javascript]
      <script type="text/javascript">
      $(document).ready(function(){
      alert(“welcome”);
      });
      </script>
      [/javascript]

      All’avvio della pagina apparirà un alert che vi dà il benvenuto. “Ovvio!”, direte voi, “è la tecnica JQuery per  eseguire del codice al caricamento della pagina!”. Ma allora che c’è di strano? Un momento… JQuery non è stato importato nella pagina? E allora da dove viene?
      Viene naturalmente da Primefaces. Infatti come abbiamo detto all’inizio di questo articolo, JQuery è integrato nel framework e dunque che ragione ci sarebbe di non poterlo avere a nostra disposizione anche per altro? Comodo, non trovate?

10 thoughts on “Optimus PrimeFaces, JSF in leggerezza (e abbondanza…)”

  1. scusa, ma il server tomcat è de essere configurato in qualche modo o avendo tutto nudo e crudo devo eseguire brutalmente le tue istruzioni? 

    1. Segui brutalmente le mie istruzioni, qualche volta, se non ti dovesse funzionare collegati a http://localhost:8080/PrimeFacesTest/index.xhtml, 
      poi successivamente l’applicazione sarà accessibile anche da http://localhost:8080/PrimeFacesTest/ .
      Non so perchè di questo comportamento…

    1. Sinceramente con sicurezza non saprei, perchè non ho mai utilizzato Primefaces su websphere, ma suppongo che siano gli stessi accorgimenti di JBoss

  2. Salve.
    Sto iniziando a usare PrimeFaces dopo essere rimasto impresso dalla ricchezza e dalla relativa semplicità d’uso dei componenti, ma sto avendo problemi con le request ajax.
    In pratica queste non funzionano e qualunque componente scatena una normale request; mi rendo conto di ciò sia per il fatto che la pagina viene refreshata tutta (si vede il browser che ricarica tutta la pagina) e perché il componente non sembra funzionare.
    C’è forse qualcosa da configurare che mi sta sfuggendo? Il web.xml mi sembra pressoché identico.

    1. Ciao,
      difficile darti una mano senza vedere almeno il codice della pagina. Posso provare con gli errori classici: stai usando h:commandButton invece di p:commnadButton? Sicuro che il tag h:form sia presente? Non è che al contrario hai due h:form annidati? Sono indicazioni basilari ma spero ti siano d’aiuto

      1. Grazie infinite per avermi risposto, non osavo sperare che dopo 2 anni dagli ultimi commenti qualcuno lo facesse; grazie davvero.
        Allora, sì, non vedendo il codice è difficile, se vuoi lo incollo qui.
        Comunque sì, questi errori banali che mi hai segnalato non li avevo fatti, ho ricontrollato e il componente è un p:commandButton, la h:form è unica ma la pagina dove è presente eredita da un template, con i tag ui:insert; magari il problema è questo.
        Siccome il progetto è basato su file di build di ant preesistenti, su NetBeans è un progetto freeform, non è stato creato con il template di NB. Sapendo questo, ho provato a ricreare l’applicazione con i template di NB e la stessa pagina, con lo stesso codice, funziona correttamente, con PrimeFaces che fa richieste ajax.
        A questo punto mi viene in mente che potrebbe essere piuttosto un problema di configurazione, ma sinceramente il mio web.xml è praticamente identico a quello del tuo esempio.
        Non so cos’altro possa essere.

        1. Ciao, non so se il web.xml c’entra davvero, il JSF ti funziona se ho capito bene. Non ci sono riferimenti a PrimeFaces perché si attiva da solo (il jar è un web-fragment). Il fatto che tutto funzioni ricreando il progetto mi fa venire il dubbio sull’efficacia dell’ant, forse rompe qualcosa nella build del progetto: sicuro che i war prodotti da NB e dall’ant siano uguali?

          1. In effetti sì, era come dici: il problema era nei file di build.
            Nel mio build.xml, che eredita da due altri file di build xml (che a loro volta ereditano anch’essi…sì, è complicato…ma ci sono affezionato!), ho ridefinito un paio di task perché mi serviva modificare e aggiungere un paio di classpath a tempo di compilazione.
            Ho revisionato il file, aggiungendo un classpath e sembra che ora funzioni tutto correttamente.
            Grazie per il prezioso aiuto, ho apprezzato davvero.

Comments are closed.