|
Vero progresso quando i vantaggi di una nuova tecnologia diventano per tutti
|
|
| Home Page |
|
| Articoli |
|
| News |
|
| Forum |
|
| Classi |
|
|
|
|
|
JavaServer Faces Framework
By
Gabriele Rigamonti
10 novembre 2005
Valutazione Acquisita:
90
|
 |
|
Il framework open source JSF e’ abbastanza giovane, ha fatto la sua prima apparizione nel 2001, rappresenta una metodologia per lo sviluppo di applicazioni web basate su componenti riutilizzabili ed espandibili. Inoltre a differenza della natura ‘stateless’ del protocollo Http, JSF permette di dotare le applicazioni di una ‘memoria’ grazie ad oggetti che memorizzano lo ‘stato’ ( il valore dei campi di un form) tra una invocazione e l’altra,inoltre le applicazioni risultano event-driven e non dipendenti da un particolare linguaggio di rappresentazione. Fai il download del codice di esempio usato nell' articolo ContoCorrente.zip
|
|
|
Struttura di JSF
|
top
|
|
User Interface Components (UI) Si tratta fondamentalmente di oggetti predefiniti che vivono sul server che interagiscono con il client. Possono essere pensati come una sorta di componenti dotati di proprietà (modellati con Javabeans),essi sono organizzati nel server come una 'view' cioè un albero di componenti che rispecchia la struttura della pagina.Oltre ai componenti standard presenti rilasciati con il framework e’ possibile crearne dei nuovi. Renders Caratteristica di spicco di JSF e’ la presenza dei Renders kit ovvero una serie di classi il cui scopo e’ quello di 'renderizzare', cioè trasformare l’albero dei componenti nel formato desiderato di visualizzazione.Ad ogni componente possono essere associati più renderizzatori, quello di default ha come target il tipo HTML.Grazie a queste funzionalità JSF crea una netta divisione tra i componenti e la loro rappresentazione. Validators Ad ogni componente e’ possibile associare dei validatori il cui scopo e’ quello di controllare (es. obbligatorietà,range ettc) la correttezza delle informazioni inserite.E’ possibile utilizzare validatori di default oppure crearne di nuovi a secondo delle proprie esigenze. Backing Beans Si tratta di Java Beans utilizzati per la memorizzazione delle informazioni associate ai componenti di input/output;inoltre contengono il codice per la realizzazione dei metodi (actions) da eseguire in risposta a particolari eventi.Grazie ai beans ad e’ possibile ‘ricordare’ il valore tra una richiesta Http e la successiva. Converters Hanno lo scopo di convertire i campi della pagina ovvero caratteri nel formato che e’ stato associato al componente e viceversa.Ad ogni componente può essere associato solamente un convertitore alla volta e come per i validatori e’ possibile crearne dei propri oppure utilizzare l’ampio set di default messo a disposizione. Events e Listeners Alcuni componenti JSF (es. bottoni,link) hanno la capacità di generare degli eventi, che mediante degli ascoltatori possono essere intercettati ed utilizzati per generare le opportune azioni. Ad esempio le actions sono particolari eventi che ritornano una risposta: il cosiddetto ‘outcome’ il cui valore determina la prossima pagina da visualizzare. Messages Sono componenti che permettono di associare a loro volta informazioni ad altri componenti come ad esempio i messaggi provenienti dai validatori. Navigation System Come già brevemente accennato precedentemente, grazie a degli outcome come risultato di azioni è possibile determinare il flusso logico dell’applicazione.Ad esempio il risultato ‘errore’ generato da un validatore determinerà la visualizzazione di una pagina di errore. Le associazioni outcome pagina/azione vengono definite mediante un file di configurazione.Ne deriva che la logica dell’applicazione può essere modificata senza intervenire sul codice.
|
|
JSF Request LifeCycle
|
top
|
|
Il processo ha inizio con l’invio della richiesta da parte del client che viene successivamente intercettata dalla Servlet JSF (ServletFaces) di controllo definita nel file web.xml e si basa su sei fasi.
Fig. 1 Ciclo di una richiesta JSF Restore View Una vista rappresenta l’insieme dei componenti che fanno parte di una pagina.Ogni vista è caratterizzata in modo univoco da un identificatore.Pensiamo alla vista come una struttura ad albero nella quale le singole foglie sono rappresentate dai componenti mentre l’identificatore ne e’ la radice (figura 2).Compito di questa fase e’ la costruzione,nel caso della prima invocazione, oppure la ricostruzione della struttura sopra descritta nel caso di richiesta successiva.La vista viene associata generalmente a livello del server nell’oggetto FacesContext.Quando si tratta di una richiesta proveniente dalla pagina stessa (postback) l’elaborazione procede verso la fase successiva mentre nel caso di richiesta iniziale JSF salterà direttamente all’ultima fase (Render). Apply Request Values In questa fase il framework estrae per ogni componente di input il valore che è stato inviato con la richiesta.Questo valore viene associato al componente all’interno della vista.Per alcuni componenti è possibile specificare la proprietà immediate che gioca un ruolo importante durante il ciclo di elaborazione.Se viene impostata a true (default è false) allora l’eventuale controllo di validazione viene eseguito in questa fase,altrimenti viene effettuato nella fase successiva.Analoga considerazione si applica per le actions , l’attivazione della condizione immediate genera l’evento in questa fase (si noti, che in questo momento non sono state ancora eseguite le eventuali validazioni) mentre se impostata al valore di default l’evento sarà innescato solamente durante la fase : Invoke Applications. Process Validations In questa fase procedurale il framework verifica che per ogni componente di input i valori sottomessi mediante la richiesta Http soddisfino eventuali condizioni richieste (come ad esempio l’obbligatorietà, la lunghezza minima e massima ettc).Prima è comunque necessaria una conversione (eseguita da convertitori di default o creati dall’utente).Se entrambe le conversioni e le validazioni hanno esito positivo (nessun errore) il processo prosegue verso la fase successiva altrimenti sarà eseguito il render della pagina. Update Model Values In questo momento i componenti hanno associato i loro valori che risultano correttamente convertiti e validati per cui possono essere associati ai beans (backing beans). <h:inputText id="data" value="#{MovimentiGestione.movimento.dataEsecuzioneMovimentoVideo}" required="true” …..> <f:convertDateTime pattern="dd/MM/yyyy"/> </h:inputText> Associato al bean MovimentiGestione abbiamo definito la proprietà movimento, a sua volta un bean con la proprietà: dataEsecuzioneMovimentoVideo di tipo java.util.Date che contiene il valore inserito nel form. Grazie all’utilizzo dei beans (session) che e’ possibile dotare la nostra applicazione di memoria. Invoke Application In questo momento si e’ pronti ad invocare i metodi di ‘business’,gli eventi vengono diffusi a tutti gli ascoltatori registrati e l’elaborazione procede verso la fase successiva. Render Response Si tratta dell’ultimo passo del processo a questo punto tutti i componenti sono stati ricostruiti,le validazioni e le actions eseguite.Il framework attraversa la vista e converte il valore associato al componente ed appoggiandosi al render (default Html) costruisce la pagina che verrà visualizzata dal browser. JSF necessita di un file di configurazione:faces-config.xml per ogni applicazione.Al suo interno devono essere definite alcune caratteristiche tra cui:i backing beans,nuovi validatori e convertitori,classi di ascoltatori,files di configurazione per i messaggi,renderizzatori e regole di navigazione. Il contenuto del file di configurazione verrà analizzato in dettaglio più avanti nel corso dell’articolo. Come tutte le web application e’ necessaria la presenza il file web.xml nel quale deve essere presente la definizione della FacesServlet che ha il compito di intercettare la richiesta Http e pilotare l’intero ciclo operativo descritto precedentemente. <web-app> .... <!-- Faces Servlet --> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup> 1 </load-on-startup> </servlet> <!-- Faces Servlet Mapping --> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping> </web-app>
|
|
L’Esempio
|
top
|
|
Entriamo a questo punto nel merito della nostra applicazione che permette di eseguire semplici operazioni sui movimenti di un conto corrente ovvero: - Creazione
- Modifica
- Eliminazione
- Interrogazione
La creazione e la modifica vengono gestite dalla pagina JSP gestione.jsp. Analizzandola con dettaglio possiamo vedere come prima cosa la definizione dei tags JSF, rispettivamente con il prefisso h per i componenti Html e f per quelli del core (devono essere presenti in ogni pagina che utilizza JSF). <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> Il primo tag JSF che incontriamo è: <f:view> che definisce la radice della struttura utilizzata dal framework per rappresentare la pagina, la figura seguente ce ne dà un'idea semplificata.  Fig. 2 rappresentazione della vista associata alla pagina gestione.jsp Ad esempio, associato all’oggetto FacesContext il campo di input utilizzato per l’inserimento dell’ importo del movimento e’ identificato con il nome:form_input:conto. Soffermiamoci in dettaglio sul componente di input con id =”data” considerazioni analoghe valgono comunque anche per gli altri.Tra le proprietà troviamo: value="#{MovimentiGestione.movimento.dataEsecuzioneMovimentoVideo}" che permette di associare il valore inserito a video al bean MovimentiGestione mediante la proprietà movimento (che essendo di tipo MovimentoDTO contiene a sua volta la proprietà dataEsecuzioneMovimentoVideo) solo se la validazione di tutti i componenti ha avuto esito positivo. required="true" il campo e’ obbligatorio, la validazione e’ completamente a carico del framework. maxlength="10" size="10" definiscono le caratteristiche visive del componente. <f:convertDateTime pattern="dd/MM/yyyy"/> In questo caso stiamo utilizzando una funzionalità presente nel framework ovvero la conversione (da tipo String) nel formato java.util.Date utilizzando un pattern predefinito.La conversione e la verifica sono completamente a carico di JSF (Fig. 3). La descrizione che appare prima del campo è ottenuta utilizzando il codice: <h:outputLabel for="data"> <h:outputText id="data_label" value="Data (gg/mm/aaaa) * : "/> </h:outputLabel> la proprietà for indica che la label è da associare al componente con id data. In caso di errore durante la fase di conversione/validazione i messaggi generati dal framework posso essere visualizzati utilizzando il seguente tag: <h:message for="data" style="color: red" /> Vale la pena soffermare inoltre l’attenzione sul componente con id=”conto” utilizzato per modellare un tag HTML di tipo select: <h:selectOneListbox id="conto" size="1" value="#{MovimentiGestione.movimento.contoMovimento}"> <f:selectItem value="#{ContoNumero1}"/> <f:selectItem value="#{ContoNumero2}"/> <f:selectItem value="#{ContoNumero3}"/> </h:selectOneListbox> Ogni singolo elemento è rappresentato da un bean di tipo javax.faces.model.SelectItem che contiene due proprietà di tipo String: label e value contenenti i riferimenti del conto corrente.E più semplicemente: <h:selectOneListbox id="segno" size="1" value="#{MovimentiGestione.movimento.segnoMovimento}"> <f:selectItem itemLabel="+" itemValue="+"/> <f:selectItem itemLabel="-" itemValue="-"/> </h:selectOneListbox> In questo caso i singoli elementi sono definiti direttamente utilizzando una costante di tipo String. Analizziamo le azioni che è possibile generare dalla pagina gestione.jsp utilizzando il bottone “Esegui”: <h:commandButtonid="esegui"value="Esegui"action="#{MovimentiGestione.gestioneMovimentoAction}" /> Per prima cosa notiamo la mancanza della proprietà immediate che sta a significare che l’ascoltatore gestioneMovimentoAction associato al bean MovimentiGestione viene invocato durante la fase ‘Invoke Applications’,quindi quando tutti i campi del form sono stati validati. Analizzando più in dettaglio il metodo invocato si nota che il suo compito principale è quello di verificare per prima cosa se si tratta di un nuovo movimento oppure di una modifica e successivamente procedere con l’operazione sul database. public String gestioneMovimentoAction() { MovimentoDTO record=null; String mess; boolean nuovo=false; try { record= dbu.recuperaMovimento(this.movimento); if (record == null) { nuovo=true; } if (nuovo) { dbu.inserisceMovimento(this.movimento); //inserisce } else { dbu.aggiornaMovimento(this.movimento); //aggiorna } } catch(ErroreGestioneMovimento em){ em.printStackTrace(); return "errore"; } FacesContext context = FacesContext.getCurrentInstance(); Application application = context.getApplication( ); String messageBundleName = application.getMessageBundle( ); Locale locale = context.getViewRoot( ).getLocale( ); ResourceBundle resource = ResourceBundle.getBundle(messageBundleName, locale); if (nuovo) { mess = resource.getString("banking.Messaggi.INSERIMENTO_ESEGUITO"); } else { mess = resource.getString("banking.Messaggi.AGGIORNAMENTO_ESEGUITO"); } FacesMessage message=new FacesMessage(); message.setSeverity(FacesMessage.SEVERITY_INFO); message.setSummary(mess); message.setDetail(mess); context.addMessage("form_input:info_msg",message); return "gestione"; } L’espressione this.movimento identifica il bean le cui proprietà contengono il valore dei campi che abbiamo inserito mediate il form. Qualora ci fosse un errore a livello di database l’azione ritornerà come outcome il valore: “errore” che ridirigerà l’applicazione verso la pagina errore.jsp. Nel caso in cui non venga sollevata nessuna eccezione, si e’ scelto di visualizzare un messaggio informativo sull’esito positivo dell’operazione. Passando attraverso l’oggetto Application associato a FacesContext viene recuperato il riferimento al file dei messaggi personalizzati (tenendo conto dell’internazionalizzazione), successivamente FacesMessage e’ popolato con il testo del messaggio ed il livello di attenzione (INFO in questo caso) ed associato al componente definito precedentemente nella nostra pagina jsp ovvero: <h:outputText id="info_msg"/> <h:message style="color: red" for="info_msg"/> Il metodo termina con il passaggio del parametro di navigazione contenente il valore ‘gestione’ che fa si che venga riemessa la pagina corrente.
 Fig. 3 validazione campi del form
 Fig. 4 creazione movimento Passiamo ora ad analizzare la fase di interrogazione dei movimenti presenti in uno o più conti correnti ed implementata dalla pagina selezione.jsp.
 Fig. 5 form di selezione Come si vede dalla figura precedente nella pagina di selezione vengono presentati due campi di input (opzionali) utilizzati per definire il range di selezione delle date e un campo select per definire il conto corrente da utilizzare. Il bottone ‘Visualizza’ genererà l’evento responsabile dell’interrogazione del database e la rivisualizzazione (postback) della pagina che conterrà gli eventuali movimenti che soddisfano le condizioni di ricerca. <h:commandButton id="esegui" value="Visualizza" action="#{MovimentiEseguiti.listaMovimentiAction}" /> public String listaMovimentiAction() { FacesContext context = FacesContext.getCurrentInstance(); ServletContext servletContext=(ServletContext)context.getExternalContext().getContext(); DataBaseUtility dbu=(DataBaseUtility)servletContext.getAttribute("DATABASE"); try { this.setMovimentiPeriodo(dbu.getEstrattoConto(this.dataEsecuzioneMovimentoDa,this.dataEsecuzioneMovimentoA,this.contoMovimento)); this.setSaldoPeriodo(dbu.getSaldoPeriodo(this.dataEsecuzioneMovimentoDa,this.dataEsecuzioneMovimentoA,this.contoMovimento)); //outcome verso la lista dei movimenti selezionati return "lista"; } catch(ErroreGestioneMovimento em) { return "errore"; } } Il risultato della selezione viene modellato utilizzando il componente HtmlDataTable che viene decodificato (renderizzato) nel componente HTML table. Si tratta di un componente pensato per visualizzare i dati in formato appunto tabellare associati ad una fonte di dati, come ad esempio: il result set , oppure una collezione di oggetti ad esempio: set,liste o arrays. Grazie ad una ricca serie di proprietà, e’ possibile ad esempio, impostare il numero massimo di records da visualizzare, oppure definire il numero del primo record,all’interno di quelli selezionati, che dovrà apparire. <h:dataTable id="tabmovimenti" var="movimenti" value="#{MovimentiEseguiti.movimentiPeriodo}" binding="#{MovimentiGestione.tabellaMovimenti}" > La proprietà value contiene il riferimento alla proprietà: movimentiPeriodo di tipo ArrayList e contenente la collezione (eventualmente vuota) di oggetti MovimentoDTO ognuno dei quali rappresenta un movimento. L’altra proprietà: var e’ semplicemente il nome simbolico utilizzato per riferirisi alla sorgente di dati (MovimentiEseguiti.movimentiPeriodo) associata al componente HtmldataTable. La proprietà binding permette di collegare, o per meglio dire sincronizzare, il componente con un bean in modo tale che possa essere manipolato da quest’ultimo;nel nostro caso, MovimentiGestione mediante la proprietà tabellaMovimenti (il cui tipo e’ UIData) contiene un riferimento al componente HtmlDataTable. Ogni colonna della tabella viene definita mediante il tag <h:column>, le intestazioni di ogni colonna sono ottenute grazie al tag <f:facet>. I facets possono essere pensati come una sorta di componenti utilizzati per definire delle relazioni o per meglio dire per la definizione di componenti subordinati come ad esempio: header e footer. <h:column> <f:facet name="header"> <h:outputText value="Data"/> </f:facet> <h:outputText value="#{movimenti.dataEsecuzioneMovimentoVideo}"> <f:convertDateTime pattern="dd/MM/yyyy"/> </h:outputText> </h:column> 
Fig. 6 form con i movimenti selezionati Molto interessanti da notare sono le due colonne nelle quali compare il tag <h:commandLink> che permette la generazione di due eventi rispettivamente:
- ContoCorrenteBean.editMovimentoAction
- ContoCorrenteBean.caricaMovimentoDaEliminareAction
Il primo si fa carico recupero delle informazioni associate alla riga selezionata ed alla successiva invocazione della pagina gestione.jsp,la seconda azione esegue un compito analogo: recupera le informazioni del movimento selezionato e ridirige l’applicazione alla pagina elimina.jsp (i singoli campi sono protetti) dove e’ possibile procedere con l’operazione di cancellazione. Analizziamo in dettaglio il codice generato in risposta al link associato alla editazione (considerazioni analoghe si applicano anche per la cancellazione). public String editMovimentoAction() { this.movimento=(MovimentoDTO)this.getTabellaMovimenti().getRowData(); try { //Rilegge il record in caso di modifica MovimentoDTO record= dbu.recuperaMovimento(this.movimento); if (record != null) { this.movimento=record; } else { this.movimento=new MovimentoDTO(); return "nuovo"; } } catch (SQLException sqle) { sqle.printStackTrace(); return "error"; } return "edita"; } Il metodo sfrutta il concetto di binding introdotto precedentemente,this.getTabellaMovimento contiene un riferimento ad un oggetto di tipo UIData, ovvero il componente che HtmlDataTable definito nella pagina seleziona.jsp. this.getTabellaMovimenti.getRowData() ritorna un Object, che mediante casting, è ricondotto ad un oggetto di tipo MovimentiDTO (ovvero la riga selezionata) utilizzato successivamente per accedere al database. E’ interessante anche osservare il link che troviamo nella pagina gestione.jsp e cancella.jsp mediante il quale l’applicazione viene indirizzata alla pagina selezione.jsp. <h:commandLink action="#{MovimentiEseguiti.listaMovimentiAction}" id="lista" immediate="true"> <h:outputText value="Lista Movimenti"/> </h:commandLink> Prima di riemettere la pagina di selezione viene invocato l’ascoltatore MovimentiEseguiti.listaMovimentiAction (si tratta della stessa azione generata dalla pagina selezione.jsp con la pressione del tasto comando Visualizza) così facendo vengono visualizzate le eventuali modifiche intercorse sui movimenti.
|
|
Il file di configurazione
|
top
|
|
Oltre al file di configurazione web.xml che definisce la FacesServlet di controllo il framework necessità del file faces-config.xml mediante il quale e’ possibile personalizzare la nostra applicazione.In questo file trovano posto: -
Dichiarazione Beans (Beans facility) -
Regole di navigazione -
Validatori e Convertitori personalizzati -
Gestione eventi -
Renders Kit -
Supporto per i messaggi e l’internazionalizzazione <managed-bean> <managed-bean-name>MovimentiGestione</managed-bean-name <managed-bean-class>banking.MovimentiGestione</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>MovimentiEseguiti</managed-bean-name> <managed-bean-class>banking.MovimentiEseguiti</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> <managed-bean> <managed-bean-name>ContoNumero1</managed-bean-name> <managed-bean-class>javax.faces.model.SelectItem</managed-bean-class> <managed-bean-scope>none</managed-bean-scope> <managed-property> <property-name>value</property-name> <property-class>java.lang.String</property-class> <value>Conto_Corrente_BancaIntesa</value> </managed-property> <managed-property> <property-name>label</property-name> <property-class>java.lang.String</property-class> <value>Banca Intesa</value> </managed-property> </managed-bean> ….. </managed-bean>
Dichiariamo il nome del bean,la sua classe ed il suo scope, nel nostro caso Session, questo significa che verrà creato solamente una volta al momento della creazione della sessione e rimarrà attivo fino a che la sessione non verrà chiusa (o scada). E’ possibile inoltre specificare come scope anche i valori Application Request e None.Un bean con scope Session viene utilizzato per la memorizzazione (proprietà value) dei valori dei campi del form tra una richiesta e la successiva. <navigation-rule> <from-view-id>/gestione.jsp</from-view-id> <navigation-case> <from-outcome>gestione</from-outcome> <to-view-id>/gestione.jsp</to-view-id> </navigation-case> <navigation-case> <from-action>#{MovimentiEseguiti.listaMovimentiAction}</from-action> <to-view-id>/selezione.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/selezione.jsp</from-view-id> <navigation-case> <from-action>#{MovimentiGestione.editMovimentoAction}</from-action> <to-view-id>/gestione.jsp</to-view-id> </navigation-case> <navigation-case> <from-action>#{MovimentiGestione.nuovoMovimentoAction}</from-action> <from-outcome>nuovo</from-outcome> <to-view-id>/gestione.jsp</to-view-id> </navigation-case> <navigation-case> <from-action>#{MovimentiGestione.caricaMovimentoDaEliminareAction}</from-action> <to-view-id>/elimina.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>lista</from-outcome> <to-view-id>/selezione.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/elimina.jsp</from-view-id> <navigation-case> <from-outcome>nuovo</from-outcome> <to-view-id>/gestione.jsp</to-view-id> </navigation-case> <navigation-case> <from-action>#{MovimentiEseguiti.listaMovimentiAction}</from-action> <to-view-id>/selezione.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <navigation-case> <from-outcome>errore</from-outcome> <to-view-id>/errore.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <from-view-id>/errore.jsp</from-view-id> <navigation-case> <from-action>#{MovimentiEseguiti.listaMovimentiAction}</from-action> <to-view-id>/selezione.jsp</to-view-id> </navigation-case> </navigation-rule>
Osserviamo ad esempio le regole di navigazione definite per la pagina selezione.jsp e notiamo che se l’invocazione dell’azione MovimentiGestione.editMovimentoAction ritorna la risposta ‘gestione’ verrà visualizzata la pagina gestione.jsp analogamente se l’azione: MovimentiGestione.nuovoMovimentoAction ritorna l’outcome ‘nuovo’ anche in questo caso la pagina visualizzata sarà gestione.jsp. Come ultima analisi notiamo che da qualsiasi pagina io provenga il risultato ‘errore’ determina la visualizzazione della pagina errore.jsp. <application> <locale-config> <default-locale>IT</default-locale> </locale-config> <message-bundle>banking.messaggi_IT</message-bundle> </application>
Il file contenente i messaggi personalizzati (banking.messaggi_IT) ci permette di eseguire l’override dei messaggi del framework e inoltre di definirne dei nuovi. javax.faces.component.UIInput.REQUIRED=Valore Obbligatorio. javax.faces.component.UIInput.CONVERSION=Il Formato inserito non e' corretto. javax.faces.validator.DoubleRangeValidator.NOT_IN_RANGE=Il valore non e' nel range consentito javax.faces.validator.DoubleRangeValidator.MAXIMUM_MESSAGE_ID=Valore superiore al massimo valore consentito javax.faces.validator.DoubleRangeValidator.MINIMUM_MESSAGE_ID=Valore inferirore al minimo valore consentito javax.faces.validator.DoubleRangeValidator.TYPE=Il tipo inserito non e' corretto javax.faces.validator.LongRangeValidator.MAXIMUM_MESSAGE_ID=Valore superiore al massimo valore consentito javax.faces.validator.LongRangeValidator.MINIMUM_MESSAGE_ID=Valore inferirore al minimo valore consentito javax.faces.validator.LongRangeValidator.TYPE=Il tipo inserito non e' corretto javax.faces.validator.NOT_IN_RANGE=Valore non presente nel range {0} and {1}. .............................................................................................. banking.Messaggi.INSERIMENTO_ESEGUITO=Il movimento e' stato creato banking.Messaggi.AGGIORNAMENTO_ESEGUITO=Il movimento e' stato aggiornato
|
|
Il test
|
top
|
|
Il nome del database utilizzato nell’applicazione e’ conticorrenti, la tabella contenente i movimenti e’ definita mediante lo schema: CREATE TABLE `conticorrenti`.`movimenti` ( `datamovimento` INTEGER UNSIGNED NOT NULL, `oramovimento` INTEGER UNSIGNED NOT NULL, `contocorrente` VARCHAR(30) NOT NULL, `importomovimento` FLOAT NOT NULL, `segnomovimento` VARCHAR(1) NOT NULL, `descrizionemovimento` VARCHAR(50) NOT NULL, PRIMARY KEY(`datamovimento`, `oramovimento`, `contocorrente`) ) TYPE = InnoDB; Nello specifico è stato utilizzato come DBMS MySql nella versione 4.0, ma è possibile usarne uno di proprio piacimento purchè si disponga del driver opportuno.Per MySql è necessario disporre del driver connector/J reperibile al link: http://dev.mysql.com/downloads/connector/j/3.0.html. Una volta scaricato va scompattato e il file: mysql-connector-java-3.0.17-ga-bin.jar va copiato nella cartella lib della nostra applicazione. Le credenziali per l’accesso al database sono presenti nel file web.xml e possono essere modificate liberamente. … <!-- data base --> <context-param> <param-name>jdbcDriver</param-name> <param-value>com.mysql.jdbc.Driver</param-value> </context-param> <context-param> <param-name>dbUrl</param-name> <param-value>jdbc:mysql://127.0.0.1:3306/conticorrenti</param-value> </context-param> <context-param> <param-name>dbUserName</param-name> <param-value>root</param-value> </context-param> <context-param> <param-name>dbPassword</param-name> <param-value></param-value> </context-param> La connessione con il db viene stabilita al momento delle creazione della sessione grazie alla classe ApplicationListener (implementa ServletContextListener) e viene distrutta al momento della chiusura della sessione. La struttura dell’applicazione Web e’ la seguente:  Fig. 7 struttura della applicazione web Nella cartella lib devono essere presenti i seguenti file jar:  Fig. 8 elenco dei jar nella directory lib Per eseguire l’applicazione con il Servlet container Tomcat, (il test è stato eseguito con la 5.0) dopo aver apportato le eventuali personalizzazioni, basta semplicemente copiare la directory ContoCorrente nella directory webapps e lanciare il server.L’invocazione avviene mediante: http://127.0.0.1:8080/ContoCorrente/faces/selezione.jsp Esistono diverse implementazioni di JSF nell’ esempio e’ stata utilizzata la Reference Implementation della Sun scaricabile dal link:http://java.sun.com/j2ee/javaserverfaces/download.html, ma esistono anche altre implementazioni come ad esempio MyFaces della Apache Foundation o quelle sviluppate da Oracle ed IBM che offrono un numero maggiore di componenti.
|
|
Conclusioni
|
top
|
|
L’esempio riporto rappresenta il punto di partenza per lo studio del framework JSF e puo’ essere facilmente adattato per funzionare anche con altre implementazioni. L’applicazione e’ stata creata utilizzando lo strumento di sviluppo Exadel Studio.
|
|
Risorse
|
top
|
Ambienti di Sviluppo: Sun Java Studio Creator 2004 Exadel Studio Implementazioni : http://java.sun.com/j2ee/javaserverfaces/download.html http://myfaces.apache.org/ Server: Apache Tomcat Bibliografia e tutorial JavaServer Faces in Action Kito D.Mann http://www.jsfcentral.com
|
|
|

Eccetto dove diversamente specificato, i contenuti di questo sito sono rilasciati sotto licenza Creative Commons
|
|
|