Generalmente una cosa del genere viene modellata usando 4 componenti:
- Una pagina XHTML che rappresenta la View, dove l'utente interagisce (indica i termini di ricerca e clicca sul pulsante per effettuare la ricerca)
- Una pagina XHTML che rappresenta la View di arrivo, dopo aver effettuato la ricerca, con i risultati.
- Un backing bean che mappa tutte le azioni che l'utente può fare nella pagina di view
- Un EJB (Enterprise JavaBean) (stateless session bean) che verrà usato dal backing bean: si occupa di effettuare materialmente le operazioni sul DB e restituire i risultati di queste operazioni al backing bean, il quale le renderà disponibili alla view.
Vediamo una bozza delle tre componenti.
La prima pagina XHTML, con il form per la ricerca:
codice:<?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:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets"> <h:body> <h:form> <h:panelGrid columns="2" id="frmRicerca"> <h:outputText value="Testo da ricercare:" /> <h:inputText value="#{myBean.textSearch}" id="srcText" label="Testo da ricercare" /> </h:panelGrid> <h:commandButton type="submit" value="Cerca" action="#{myBean.executeSearch}" /> </h:form> </h:body> </html>
Da notare subito due cose:
1) l'inputText è associato (attributo "value") alla proprietà "textSearch" del backing-bean "myBean"; essendo un bean, nella relativa classe vanno creati i relativi metodi getter/setter per la proprietà. Se la proprietà sarà in "sola lettura" sarà sufficiente il metodo getter. Non è il nostro caso: l'utente deve poter "popolare" il valore del campo di ricerca del bean.
2) la action del pulsante (commandButton) è associata ad un metodo del backing-bean ( metodo executeSearch() ); tale metodo deve ritornare una stringa, che rappresenterà l'outcome, cioè una stringa che sarà valutata da JSF per capire a quale pagina reindirizzare l'utente dopo che il lavoro del metodo è stato eseguito.
Vediamo il backing-bean:
codice:package it.test; public class SearchBean implements java.io.Serializable { ... @EJB private DatabaseOperations dbOperations; // Sarà il mio EJB con cui effettuerò le operazioni sul DB ... private String textSearch; // Conterrà il testo da cercare, digitato dall'utente private List<Record> lstRisultato; // Conterrà il risultato della ricerca, come lista di "Record" (non meglio definiti) ... // Getter e setter public String getTextSearch() { return textSearch; } public void setTextSearch(String textSearch) { this.textSearch = textSearch; } public List<Record> getLstRisultato() { return lstRisultato; } // La action per il pulsante public String executeSearch() { // Qui effettuo la ricerca sul DB usando il mio EJB lstRisultato = dbOperations.ricerca( textSearch ); // Qui potrei usare un minimo di logica applicativa per decidere // dove reindirizzare l'utente in base ai risultati (ad esempio, potrei // mandarlo alla pagina dei risultati se e solo se la lista non è nulla/vuota // altrimenti indirizzarlo ad una pagina di errore, o quant'altro... per il // nostro esempio, reindirizziamo sempre l'utente alla stessa pagina) return "risultati"; } }
Da notare che la stringa di output del metodo executeSearch() può essere qualunque cosa: può essere il nome di una pagina XHTML o una stringa che identifica una navigazione (nel qual caso dovrai provvedere a fornire una navigation-rule (trovi svariati esempi on-line). Nel nostro caso JSF semplicemente cercherà la pagina "risultati.xhtml" e reindirizzerà lì l'utente.
L'EJB che effettua le operazioni sul DB non è particolarmente interessante:
codice:@Stateless public class DatabaseOperations { // Qui potrei utilizzare un framework di persistenza per il DB // oppure ottenere una risorsa JDBC direttamente dall'Application Server/Servlet Container // oppure ancora stabilire al volo una connessione al DB, usarla e quindi rilasciarla ... public List<Record> ricerca(String strToSearch) { List<Record> ret = null; StringBuilder sql = new StringBuilder(); sql.append("SELECT * "); sql.append("FROM Tabella "); sql.append("WHERE mioCampo LIKE ?"); PreparedStatement pstmt = null; ResultSet rs = null; try { pstmt = con.prepareStatement( sql.toString() ); pstmt.setString(1, "%" + strToSearch + "%"); rs = pstmt.executeQuery(); if (rs != null) { ret = new ArrayList<Record>(); while( rs.next() ) { Record rec = createRecordFromResultSet( rs ); ret.add( rec ); } } } catch (Exception e) { logger.log("Errore nella ricerca", e); } finally { if (rs != null) { try { rs.close(); } catch (Exception e) { } } if (pstmt != null) { try { pstmt.close(); } catch (Exception e) { } } } return ret; } ... }
Infine la pagina dei risultati
In questo caso ho usato un ui:repeat per scorrere l'arraylist restituito dal getter "getLstRisultato()" e stampare in output ogni singolo record... ovviamente puoi usare qualsiasi cosa: una tabella, una lista, un framework esterno (come RichFaces o PrimeFaces o altro per la composizione della pagina risultati).codice:<?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:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets"> <h:body> <h:form> <h:panelGrid columns="2" id="frmRisultati"> <ui:repeat value="#{myBean.lstRisultato}" var="rec"> <h:oputputText value="#{rec.blabla}" /> </ui:repeat> </h:panelGrid> </h:form> </h:body> </html>
Una cosa che va fatta è informare il framework JSF del fatto che vogliamo avere il backing-bean come managed-bean. Quindi nel faces-config (o in altro file XML opportunamente mappato nel web.xml) andiamo a definire il managed-bean relativo al nostro backing-bean:
codice:<faces-config version="2.0" 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"> <managed-bean> <managed-bean-name>myBean</managed-bean-name> <managed-bean-class>it.test.SearchBean</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> ... </faces-config>
E questo dovrebbe essere più o meno tutto (ho scritto il tutto al volo, spero sia abbastanza chiaro).
Ciao.![]()



Rispondi quotando