In questo articolo analizzeremo il progetto Apache MyFaces che ha come scopo di creare e manutenere una implementazione Open Source (secondo la licenza Apache versione 2) delle specifiche JavaServer Faces, inoltre include una serie di sotto progetti che forniscono componenti aggiuntivi, servizi di integrazione per altre tecnologie (ad esempio Portali), etc... .La lista completa dei sotto progetti include: -Core: un'implementazione delle specifiche e dei componenti JSF 1.1, JSF 1.2, JSF 2.0 e JSF 2.1 come specificato dalle JSR 127, JSR 252 and JSR 314 rispettivamente; -Portlet Bridge: un'implementazione delle specifiche JSF Portlet Bridge come specificato dalla JSR 301; -Tomahawk: un set di componenti JSF components creati dal team di sviluppo MyFaces prima che passasse sotto l'egida Apache; -Trinidad: un set di componenti JSF donati a MyFaces da Oracle, prima conosciuti come ADF Faces; -Tobago: un set di componenti JSF sviluppati per MyFaces da Atanion GmbH; -Orchestra: un framework utilizzato per gestire la persistenza delle sessioni attraverso scope diversi; -Extensions Validator: un framework per la validazione JSF centrica, basato sulle annotazioni; -Others: sotto progetti più piccoli quali ad esempio MyFaces Commons e MyFaces Shared.
In questo articolo analizzeremo il progetto Apache MyFaces che ha come scopo di creare e manutenere una implementazione Open Source (secondo la licenza Apache versione 2) delle specifiche JavaServer Faces, inoltre include una serie di sotto progetti che forniscono componenti aggiuntivi, servizi di integrazione per altre tecnologie (ad esempio Portali), etc… .
La lista completa dei sotto progetti include:
- Core: un’implementazione delle specifiche e dei componenti JSF 1.1, JSF 1.2, JSF 2.0 e JSF 2.1 come specificato dalle JSR 127, JSR 252 and JSR 314 rispettivamente;
- Portlet Bridge: un’implementazione delle specifiche JSF Portlet Bridge come specificato dalla JSR 301;
- Tomahawk: un set di componenti JSF components creati dal team di sviluppo MyFaces prima che passasse sotto l’egida Apache;
- Trinidad: un set di componenti JSF donati a MyFaces da Oracle, prima conosciuti come ADF Faces;
- Tobago: un set di componenti JSF sviluppati per MyFaces da Atanion GmbH;
- Orchestra: un framework utilizzato per gestire la persistenza delle sessioni attraverso scope diversi;
- Extensions Validator: un framework per la validazione JSF centrica, basato sulle annotazioni;
- Others: sotto progetti più piccoli quali ad esempio MyFaces Commons e MyFaces Shared.
Come si può notare esiste un componente Core per ogni specifica versione di JSF, dalla 1.1 alla 2.1 che è la versione più recente disponibile e che andremo ad usare nei nostri esempi. La versione JSF 2.1 richiede come requisito la JVM 1.5 o successiva, e le implementazioni JSP 2.1, JSTL 1.2 e Java Servlet 2.5.
Il componente Core si divide poi in due sottomoduli:
- MyFaces API: implementa tutte le classi che sono definite nella spefica JSF;
- MyFaces Impl: fornisce classi di supporto (invisibili) che il codice di uno sviluppatore non invoca direttamente, ma che sono necessarie per il funzionamento del framework. Ad esempio le classi di rendering per i componenti JSF.
Iniziamo andando a scaricare le librerie Core, che troviamo a questo indirizzo:
http://myfaces.apache.org/download.html
la versione più recente al momento in cui scriviamo è la 2.1.1.
Nella stessa pagina in basso troviamo i link ai download per gli altri sotto progetti, in particolare se andiamo sul link di MyFaces Tomahawk (http://myfaces.apache.org/tomahawk/download.html) possiamo recuperare un file .war di esempi che ci permettono di visionare tutti i componenti a disposizione.
Vediamo ora come creare un esempio funzionante utilizzando l’IDE Eclipse.
Dalla barra dei menu di Eclipse clicchiamo su File -> New -> Project…, nel wizard per il New Project, selezioniamo Web -> Dynamic Web Project:
Clicchiamo su Next si aprirà questo pannello:
Clicchiamo su Next finchè non arriviamo alla finestra JSF Capabilities:
Dobbiamo ora includere le librerie Core e Impl di MyFaces, lo facciamo cliccando su Manage Libraries:
Clicchiamo poi su New… e come User Library Name inseriamo MyFaces-2.1.1:
Ora possiamo includere la libreria MyFaces ed infine clicchiamo su Finish:
Dobbiamo ora includere le librerie prerequisito di MyFaces Core che sono:
- commons-beanutils-1.8.3.jar;
- commons-codec-1.3.jar;
- commons-collections-3.2.jar;
- commons-digester-1.8.jar;
- commons-logging-1.1.1.jar.
queste librerie le troviamo all’interno del pacchetto zip o tar.gz che contiene le librerie Core.
Abbiamo inoltre bisogno delle librerie da cui dipende MyFaces Tomahawk, che troviamo nel pacchetto zip o tar.gz che contiene gli esempi (http://myfaces.apache.org/tomahawk/download.html)):
- batik-awt-util-1.6-1.jar;
- batik-ext-1.6-1.jar;
- batik-gui-util-1.6-1.jar;
- batik-util-1.6-1.jar;
- commons-el-1.0.jar;
- commons-fileupload-1.2.1.jar;
- commons-io-1.3.2.jar;
- commons-lang-2.4.jar;
- commons-validator-1.3.1.jar;
- jstl-1.2.jar;
- oro-2.0.8.jar;
- standard-1.1.2.jar;
- tomahawk-1.1.10.jar;
- xml-apis-1.0.b2.jar;
- xmlParserAPIs-2.0.2.jar.
Tutte queste librerie le inseriamo nella cartella WEB-INF/lib come mostrato in figura:
inserendole in quella cartella, le librerie saranno caricate automaticamente all’interno del Build Path del progetto, sotto la voce Web App libraries:
Dobbiamo ora configurare la Web Application andando a modificare il file web.xml. Lo apriamo in Eclipse e lo rendiamo uguale al seguente:
<?xml version="1.0" encoding="ASCII"?> <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_3_0.xsd" version="3.0"> <display-name>TestMyFaces</display-name> <context-param> <param-name>org.apache.myfaces.CHECK_EXTENSIONS_FILTER</param-name> <param-value>true</param-value> </context-param> <filter> <filter-name>extensionsFilter</filter-name> <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter </filter-class> <init-param> <param-name>uploadMaxFileSize</param-name> <param-value>100m</param-value> </init-param> <init-param> <param-name>uploadThresholdSize</param-name> <param-value>100k</param-value> </init-param> </filter> <filter-mapping> <filter-name>extensionsFilter</filter-name> <url-pattern>*.jsf</url-pattern> </filter-mapping> <filter-mapping> <filter-name>extensionsFilter</filter-name> <url-pattern>/faces/*</url-pattern> </filter-mapping> <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> <context-param> <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name> <param-value>resources.application</param-value> </context-param> <listener> <listener-class>org.apache.myfaces.webapp.StartupServletContextListener</listener-class> </listener> </web-app>
Il parametro fondamentale da definire è il nome del Filtro extensionFilter mappato sulla classe org.apache.myfaces.webapp.filter.ExtensionsFilter è questa il cuore del framework che intercetta le chiamate durante il ciclo di vita della JSF. All’interno del web.xml possono essere specificate dei parametri iniziali che sono definiti nella classe MyFacesConfig, tali parametri possono essere omessi e di conseguenza vengono settati al valore di default.Creiamo ora una pagina di index della nostra applicazione che non farà altro che un redirect verso una pagina JSF (in formato xhtml):
<html> <head> </head> <body> <jsp:forward page="/faces/testjsf.jsp" /> </body> </html>Creiamo ora una pagina JSP, facendo click col tasto destro su WebContent -> New -> Other -> Web -> JSP File, inseriamo un nome ad esempio MyFacesPage ed infine scegliamo il template come mostrato in figura:
Inseriamo il namespace dei tag Tomahawk (xmlns:t=”http://myfaces.apache.org/tomahawk”), e proviamo alcuni tag Tomahawk come ad esempio le label (t:outputLabel), gli input (t:inputText) ed un componente avanzato quale un Captcha (t:captcha):
<?xml version="1.0" encoding="ISO-8859-1" ?> <jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" version="2.0"> <jsp:directive.page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1" /> <jsp:text> <![CDATA[ <?xml version="1.0" encoding="ISO-8859-1" ?> ]]> </jsp:text> <jsp:text> <![CDATA[ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> ]]> </jsp:text> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:t="http://myfaces.apache.org/tomahawk"> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> <title>Insert title here</title> </head> <body> <f:view> <h:form id="form"> <h:panelGrid columns="2"> <t:outputLabel value="Inserisci il codice mostrato"/> <t:inputText value="#{testCaptchaBean.value}"/> <h:commandLink value="Ricarica immagine" /> <t:captcha captchaSessionKeyName="#{testCaptchaBean.sessionKeyName}" /> <h:commandButton value="Invia" action="#{testCaptchaBean.check}"/> <t:outputLabel value="#{testCaptchaBean.status}"/> </h:panelGrid> </h:form> </f:view> </body> </html> </jsp:root>Ora dobbiamo definire un Bean Java che mappi e conservi i valori degli attributi value dei componenti JSF ed implementi la action invocata dal commandButton, per fare questo basta creare una classe Java nella cartella src del nostro progetto ed inserire questo codice:
package it.appuntisoftware; import javax.faces.context.FacesContext; import javax.servlet.http.HttpSession; public class TestCaptchaBean { public final static String SESSION_KEY_NAME = "SessionKeyName"; public final static String CORRETTO = "Corretto!"; public final static String SBAGLIATO = "Sbagliato"; String status; String value; public String check() { // Compara il valore del CAPTCHA con quello inserito dall'utente. String captchaValue = (String)((HttpSession) FacesContext.getCurrentInstance().getExternalContext().getSession(true)) .getAttribute(SESSION_KEY_NAME); if(captchaValue.equalsIgnoreCase(value)) { status = CORRETTO; } else { status = SBAGLIATO; } return ""; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } public String getSessionKeyName() { return SESSION_KEY_NAME; } }Infine bisogna inserire nel faces-config.xml il Bean che abbiamo creato in questo modo esso sarà istanziato automaticamente a runtime dal VariableResolver (ritorna un oggetto e lo crea se questo è referenziato per la prima volta), inoltre dobbiamo specificare lo scope del Bean che nel nostro caso sarà di tipo request:
<?xml version="1.0" encoding="UTF-8"?> <faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd" version="2.0"> <managed-bean> <managed-bean-name>testCaptchaBean</managed-bean-name> <managed-bean-class>it.appuntisoftware.TestCaptchaBean</managed-bean-class> <managed-bean-scope>request</managed-bean-scope> </managed-bean> </faces-config>A questo punto la nostra applicazione è completa, non ci resta che lanciarla sul nostro Application Server Tomcat e provarla. Se inseriamo il corretto valore del Captcha che ci viene presentato allora riceviamo come risposta il valore Corretto!, in caso contrario otteniamo il risultato Sbagliato:
COMMENTS