Java Enterprise Edition - JEE Autore: Agostino Sorbara ITIS “M. M. Milano” Indice Introduzione ………………………………………………………… Il modello Client – Server ………………………………………. 2 2 La piattaforma di sviluppo JEE …………………………..... Application Server ……………………………………………….... Servlet ……………………………………………………………………. JSP (Java Servlet Page) …………………………………………… JDBC (Java DataBase Connectivity) ………………………… Lettura dei dati da un Database ……………………….. Inserimento e modifica dei dati in un Database .. JavaBean ed Enterprise JavaBean (EJB) ………………… EJB di sessione ……................................................ EJB di entità ……………………………………………………… EJB pilotati da messaggi ……………………………………. 3 3 4 5 6 11 12 13 14 14 15 Il pattern architetturale MVC …………………………….... 16 1 Introduzione Oggi le imprese hanno necessità di estendere la loro capacità di soddisfare clienti, dipendenti e fornitori con costi più bassi e tempi di risposta nel fornire i servizi richiesti minori. In genere, le applicazioni che forniscono questi servizi devono integrare sistemi informativi aziendali esistenti (EISs) con nuove funzioni aziendali che offrono servizi ad una vasta gamma di utenti. I servizi devono essere: Altamente disponibili, per soddisfare le esigenze di ambienti di business globali. Sicuri, per proteggere la privacy degli utenti e l’integrità dell’impresa. Affidabili e scalabili, per garantire che le transazioni commerciali siano accurate e che avvengano in tempi brevi. Nella maggior parte dei casi, i servizi enterprise sono implementati come applicazioni multilivello. Le nuove tecnologie web sono utilizzati per fornire agli utenti di primo livello, un facile accesso alla complessità business, e di eliminare o ridurre drasticamente la gestione degli utenti e della formazione. La piattaforma Java Enterprise Edition (JEE) riduce il costo e la complessità di sviluppo multilivello, per i servizi forniti alle imprese. Le Applicazioni Java EE possono essere implementate rapidamente e facilmente. Java EE raggiunge questi benefici definendo un’architettura standard con i seguenti elementi: Java EE Platform - Piattaforma standard per l’hosting di applicazioni Java EE. Suite Java EE test di compatibilità - Una suite di test di compatibilità per verificare che un prodotto della piattaforma Java EE sia conforme allo standard della piattaforma Java EE. Java EE Reference Implementation - Una implementazione di riferimento per la prototipazione di applicazioni Java EE e per fornire una definizione operativa della piattaforma Java EE, stabilisce i requisiti che un prodotto JEE deve soddisfare. Il modello Client – Server L’architettura del sistema informatico è di tipo Client-Server. Il sistema è formato da due tipi di moduli: il client ed il server, che generalmente sono diverse macchine collegate in rete1. Il server contiene la logica necessaria per fornire un servizio; ad esempio gestisce le banche dati, gestisce l’aggiornamento dei dati e la loro integrità; Il client può effettuare alcune operazioni e quindi richiede un terminale con capacità elaborative (generalmente si tratta di un computer). Tipicamente il client gestisce la porzione di interfaccia utente dell’applicazione, verifica i dati inseriti e provvede ad inviare al server le richieste formulate dall’utente. In pratica il client è quella parte dell’applicazione che l’utente vede e con la quale interagisce. In un ambiente client/server, sul computer client è in esecuzione un software applicativo denominato programma client, il quale: Abilita l’utente a spedire una richiesta di informazione al server; Formatta la richiesta in modo che il server possa comprenderla; Formatta la risposta del server in modo che l’utente possa interpretarla correttamente. Mentre sul computer server viene eseguito un software applicativo chiamato programma server, il quale: Riceve una richiesta da un client e la processa; Risponde, spedendo l’informazione richiesta, al client. La logica di comunicazione del modello client – server può essere rappresentata mediante la seguente figura: 1 Per le simulazioni si utilizza un unico elaboratore che con le opportune configurazioni e settaggi svolgerà la doppia funzione sia di client che di server. 2 Figura 1 - Modello Client – Server Affinché l’interazione tra client e server possa essere effettuata, è necessario che entrambi utilizzino un linguaggio comune, ovvero un protocollo applicativo. Esempi di protocolli: Simple Mail Transfer Protocol (SMTP) per la posta elettronica; File Tranfer Protocol (FTP) per il trasferimento di file tra host; Hyper-Text Transfer Protocol (HTTP) protocollo su cui si basa il World Wide Web; Ovviamente tutti questi protocolli applicativi devono appoggiarsi sui protocolli di rete TCP/IP e sul DNS per poter effettivamente scambiare richieste e messaggi attraverso la rete. 3 La piattaforma di sviluppo JEE Java Platform, Enterprise Edition o Java EE (conosciuta, prima della versione 5, col nome di Java 2 Enterprise Edition o J2EE) è una piattaforma software di programmazione principalmente sviluppata in linguaggio di programmazione Java e ampiamente utilizzata nella programmazione Web. La piattaforma fornisce infatti API e un ambiente di runtime (JDK e JRE) per lo sviluppo e l’esecuzione di software per le imprese, compresi servizi di rete e web, nella forma di grandi applicazioni di rete a più livelli, scalabili, affidabili e sicure. La Java EE estende la Java Platform, Standard Edition (Java SE), incorporando un design basato in gran parte su componenti modulari in esecuzione su un server di applicazioni. Un’applicazione che implementa le specifiche JEE è un’applicazione distribuita multi-tier, schematizzabile in quattro layer (vedi fig. 2) Figura 2 - Architettura di una generica applicazione JEE I principali vantaggi derivanti dall’uso delle specifiche JEE per lo sviluppo di applicazioni web sono fondamentalmente quattro: Scalabilità: è possibile aumentare le funzionalità di un software in continua evoluzione, grazie anche alla peculiare proprietà di distribuibilità della tecnologia Java; Portabilità: esigenza fondamentale dell’attività di sviluppo software, permette di utilizzare una stessa applicazione JEE in Application Server diversi purché questi implementino le specifiche JEE; Efficienza: una strutturazione così intensa facilita la gestione di progetti anche molto complessi. Inoltre, grazie all’utilizzo del multi-threading di Java è possibile ottenere elevate performance per l’interazione tra Client e Server; Sicurezza: assicurata dall’elevata stratificazione dell’architettura e dalle proprietà intrinseche della tecnologia Java. Attraverso il modello proposto, si rende facile l’accesso ai dati e la loro rappresentazione in diverse forme (un browser web, un applet, un dispositivo mobile, un sistema esterno, ecc). L’Application Server Tra i più importanti elementi di un’applicazione web, vi è l’Application Server, il quale, implementando le specifiche JEE, rappresenta uno strato software che fornisce i servizi e le interfacce per la comunicazione tra tutte le componenti e permette all’applicazione di funzionare. 4 Molti degli Application Server presenti sul mercato, implementano sia il livello Web-Tier che il Business-Tier. Le applicazioni più semplici, quelle cioè che non possiedono una vera e propria logica di business, dovrebbero utilizzare Application Server con solo la proprietà di Web-Container (che ha la funzione principale di presentazione dei dati): sono chiamati Web Server e sono consigliati in queste circostanze in quanto, le risorse richieste, sono di molto inferiori. Tra i principali componenti Java gestiti da un Web-Container vi sono Servlet, JSP (Java Server Pages), JDBC (Java DataBase Connectivity) e JNDI (Java Naming and Directory Interface). Un Application Server può fornire, inoltre, un ambiente detto EJB-Container (Enterprise Java Beans Container) che contiene la logica di business dell’applicazione. Elementi fondamentali di questo ambiente sono gli Enterprise JavaBeans, le cui specifiche sono state introdotte per la prima volta da IBM nel 1997 e successivamente accorpate nelle API standard di Sun Microsystem. Il compito di un EJB-container è quello di gestire sicurezza, dettagli di persistenza e integrità delle transazioni, lasciando agli sviluppatori maggior concentrazione riguardo i problemi core business. La scelta di quale Application Server utilizzare a sostegno delle proprie applicazioni è influenzata da numerosi fattori tra cui: Tecnologie preesistenti; Costo delle licenze; Supporto a pagamento; Supporto della rete; Portabilità. I principali Application Server presenti nel panorama delle applicazioni web e che implementano lo standard JEE (chi completamente e chi in parte) sono: JBOSS; Apache Tomcat; Sun GlassFish Enterprise Server (essendo gestito direttamente da Sun implementa nel modo più completo e fedele le specifiche dello standard JEE; le versioni seguono di pari passo i nuovi rilasci delle specifiche JEE); BEA Weblogic; IBM WebSphere. Servlet La creazione di applicazioni web base, in ambiente java, deve il suo grande successo grazie ad una tecnologia introdotta per fornire agli sviluppatori un linguaggio lato server facile da usare e compatibile con la tecnologia Java. Le servlet sono degli oggetti Java residenti sul server che vengono utilizzate per costruire logiche applicative più o meno complesse in accordo al principio di programmazione multilivello. Questi oggetti sono caricati ed utilizzati dal web server che mette loro a disposizione un ambiente particolare, detto container, che si occuperà di tutti i loro aspetti, gestendone l’intero ciclo di vita. Una servlet ha la possibilità di accedere a tutte le risorse del sistema su cui risiede, permettendo in fase di programmazione di implementare le diverse funzioni sfruttando tutte le caratteristiche del sistema, nonché la potenza espressiva di un linguaggio ad oggetti come Java. La loro gestione operata da un ambiente di lavoro volto ad ottimizzare tutti gli aspetti inerenti alle risorse di sistema, consentirà una efficiente gestione delle stesse con conseguente miglioramento nelle prestazioni delle applicazioni web based. Questa tecnologia è utilizzata all’interno del Web-Container. Una Servlet ha il compito di gestire le richieste dell’utente, effettuare eventuali elaborazioni e fornire una risposta al Client, spesso mediante il protocollo di rete HTTP. La struttura di base di una Servlet è rappresentata di seguito: import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class Servlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 5 //Overriding del metodo doGet } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //Overriding del metodo doPost } } I package javax.servlet e javax.servlet.http forniscono le classi e le interfacce rispettivamente per scrivere una Servlet generica e una Servlet per il protocollo http; la propria Servlet, in quanto tale, deve implementare l’interfaccia Servlet o per lo meno estendere javax.servlet.GenericServlet. Nell’implementazione è possibile utilizzare (ed in questo caso estendere) una classe fornita dalle API di Java ovvero la classe HttpServlet, che fornisce due importanti metodi per gestire servizi HTTP: doGet() e doPost(). Questi ultimi rappresentano i metodi GET e POST del protocollo http; richiedono come parametri gli oggetti HttpServletRequest e HttpServletResponse e rappresentano rispettivamente la richiesta del client (che contiene ad esempio i dati di input per l’elaborazione) e la risposta del server (che può contenere dati di output come risultati di elaborazione). Altri metodi importanti sono: getParameter(“Param”) che raccoglie il valore di un parametro dalla richiesta HTTP e restituisce un elemento di tipo String; public class Servlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String parametro = request.getParameter(“ParamName”); } } setAttribute(String name, Object obj) che permette di associare alla variabile name un valore obj, che può essere utilizzato in seguito, nell’ambito della gestione della medesima richiesta. getAttribute(String name) questo metodo permette di accedere al valore associato a name precedentemente memorizzato. getSession() ritorna l’istanza di un oggetto che rappresenta una sessione di lavoro con l’utente. Un possibile passaggio di parametri da utente a Servlet può avvenire attraverso il metodo HTTP GET, con URL append; ad esempio: in una pagina HTML (HyperText Markup Language) è possibile trovare <a href="Path/MyServlet?ParamName=AAA">submit</a> che permette a MyServlet (all’interno del metodo doGet) di inizializzare la variabile parametro uguale alla stringa ”AAA”. funzionamento Sono costituite da codice java; Seguono un modello mvc. Per convenzione dei programmatori java quando si nomina un file il suffisso servlet rimane. La servlet estende un’interfaccia http server. Le richieste fatte dal client al server possono essere fatte con i tre metodi principali: 1) GET; 2) POST; 3) PUT. doGet rispondono alle chiamate del browser doPost La servlet è una classe java, che ricevuta una richiesta restituisce un risultato, il browser formatta la richiesta e la restituisce in HTML formattato (vedi immagine). 6 Figura 3 - Quando il metodo service riceve una richiesta di tipo GET manda in esecuzione il metodo doGet, se riceve una richiesta di topo POST invoca il metodo doPost. Questi due metodi avranno il compito di generare una risposta, solitamente sottoforma di pagina Web, e spedirla al client. Init service richiesta doGet doPost destroy Figura 4 - Il server Web può infine decidere di eliminare una servlet invocando il metodo destroy. Le richieste e le risposte sono gestite rispettivamente dalle classi HttpServletRequest e HttpServletResponse. 7 Gli oggetti generati dalla classe HttpServletRequest contengono tutte le informazioni relative alla richiesta ricevuta dal client, in particolare i valori delle variabili di ambienti, i parametri e i dati spediti dal client e il tipo di richiesta. Gli oggetti generati dalla classe HttpServletResponse consentono di controllare la risposta che verrà restituita al client. Abbiano tre tipologie di Bean SessionBean utilizzati per compiere operazioni di logica Entity Bean consentono la gestione automatizzata di alcuni aspetti relativi all’accesso ed in generale alla gestione dei dati. Message Drive Bean messaggi asincroni per il database Servlet Controller <% %> View Class … { Void … () { …. } } Model DB Fig. 5 - Analogia con il modello architetturale MVC JSP (JavaServer Pages) Il livello di presentazione nella tecnologia JEE è composto dalle JSP. Si tratta di file testuali che accanto al codice HTML, presentano codice in linguaggio Java, permettendo un utilizzo dinamico del servizio web e demarcando in maniera netta i compiti della progettazione dell’interfaccia e delle funzioni. Questa tecnologia permette di creare pagine di testo sia statiche che dinamiche. Per dinamiche s’intende che il contenuto delle pagine può essere creato includendo risultati di elaborazione, dati prelevati dal database, oppure parametri inseriti dall’utente. JSP è un buon connubio tra le funzionalità dinamiche di una Servlet e la staticità di una pagina formattata ad esempio in HTML. Infatti, l’inserimento di contenuti statici e costrutti di formattazione all’interno di una Servlet è difficoltoso, per questo motivo è preferibile utilizzare la tecnologia JSP. Vediamo in breve il contesto esecutivo. Il client richiede l’accesso al file con estensione .jsp, il quale viene processato dal WebContainer che lo trasforma in un file Java, lo compila, lo carica e lo esegue come una Servlet; ovviamente, la fase di traduzione, compilazione e caricamento viene effettuata solo la prima volta che viene individuata una richiesta alla risorsa oppure se la JSP è stata modificata. Questa tecnologia, inoltre, mette a disposizione una serie di tag e costrutti specifici. Come si vede negli esempi di implementazione, un esempio di servlet può essere il seguente 8 IndexStudente Servlet Controller IndexStudente.jsp JavaBeans View Model EJB Progetto_ lp Fig. 6 - package as.servlet; import as.ejb.StudenteSessionBeanLocal; import as.objects.LO; import as.objects.Studente; import java.io.IOException; import java.util.ArrayList; import javax.ejb.EJB; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; /** * * @author user */ public class IndexStudenteServlet extends HttpServlet { @EJB StudenteSessionBeanLocal beanStudente; protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session = request.getSession(true); int idStudente = ((Studente)session.getAttribute("studente")).getId(); ArrayList<LO> listaLO = beanStudente.visualizzaLOScaricati(idStudente); request.setAttribute("listaLO", listaLO); RequestDispatcher dispatcher = request.getRequestDispatcher("IndexStudente.jsp"); dispatcher.forward(request, response); } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } @Override public String getServletInfo() { return "Short description"; } } 9 JDBC (Java DataBase Connectivity) JDBC non è altro che l’insieme delle API che definiscono le specifiche per l’accesso a database relazionali. Fa parte sia dello standard J2SE sia di JEE. L’insieme delle classi che offrono una connettività tra Java e un DBMS, implementando le interfacce dei package java.sql e javax.sql, prende il nome di driver JDBC; le principali interfacce sono: Driver, Connection, Statement, PreparedStatement, CallableStatement, ResultSet, DatabaseMetaData, ResultSetMetaData. Le classi implementative sono normalmente contenute in pacchetti .jar che lo sviluppatore dovrà caricare nella propria applicazione. Successivamente, per poter utilizzare i driver, si dovrà aprire una connessione con il database, creare uno Statement per interrogare la base dati e gestire i risultati ottenuti. Di seguito è riportato una porzione di codice che potrebbe popolare una pagina JSP, in cui viene effettuata l’interrogazione di una base dati connessa tramite driver JDBC-ODBC. Un esempio di utilizzo di queste API, si può trovare in un SessionBean, si riporta come esempio getCanale: public Canale getCanale(int idCanale) { Statement stmt; try { stmt = JDBCConnector.getConnection().createStatement(); String query = "select * from canale where id="+idCanale+";" ; ResultSet rs = stmt.executeQuery(query) ; while (rs.next()){ int id = rs.getInt("id"); String nome= rs.getString("nome"); Canale c = new Canale(id,nome); return c; } } catch (SQLException ex) { Logger.getLogger(LoginSessionBean.class.getName()).log(Level.SEVERE, null, ex); } return null; } L’oggetto di tipo Connection preso da una classe implementata JDBCConnector consente di ottenere una connessione con il database. La classe DriverManager è incaricata di scegliere l’opportuno driver registrato, attraverso l’URL e le credenziali di accesso al database passati come parametri. L’oggetto Statement, invece, permette di effettuare interrogazioni alla base dati in linguaggio SQL, attraverso la connessione precedentemente creata. Qualora lo stesso Statement SQL sia utilizzato più volte, è consigliato servirsi, in alternativa, dell’oggetto PreparedStatement che aumenta l’efficienza dell’esecuzione della query e l’allocazione delle risorse. Infine, il ResultSet, è l’oggetto che raccoglie i dati richiesti all’interno dello Statement e li inserisce in una struttura dati opportuna. Il metodo getString(“NomeColonna”) restituisce il valore correntemente puntato dal cursore next() della colonna specificata come parametro. Se il nome della colonna non è presente nel ResultSet, non viene lanciata alcuna eccezione. Esistono diversi metodi getType(“NomeColonna”), dove Type indica il tipo di dato che si vuole estrarre dal ResultSet e che deve essere concorde al tipo di dato di “NomeColonna”. 10 Lettura dei dati da un Database Una volta configurato il driver ODBC si può passare alla lettura dei dati contenuti in un database. L’operazione completa per leggere i dati da una o più tabelle di una base di dati è suddivisa in quattro fasi: 1. Apertura e connessione al database 2. Esecuzione istruzione 3. Elaborazione risultato 4. Chiusura connessione Vediamo un esempio di codice <! -- per l’esecuzione corretta delle istruzioni SQL è necessario importare il relativo package: java.sql.* --> <% page language=”java” import=”java.sql.*” %> connection dbconn = null; // carica il file di classe del driver // per il collegamento al database con il ponte ODBC Class.forName (“sun.jdbc.odbc.JdbcOdbcDriver”); // apre la connessione con il database “miodb” dbconn = DriverManager.getConnection(“jdbc:odbc:miobd”,”admin”,”pswd”); // manda in esecuzione l’istruzione SQL Statement statement = dbconn.createStatement(); ResultSet rs = statement.executeQuery(“SELECT dato FROM tab1”); In questa parte di codice abbiamo implementato i primi due punti. L’oggetto rs contiene l’insieme dei risultati ottenuti dalla SELECT, rappresentati nella classe ResultSet. Questa classe permette di compiere una scansione di tutti i record e leggere il contenuto dei campi. // elabora i dati Whilw (rs.next()) { // ottiene il dato dat = rs.getInt(dato); // stampa a video out.println(dat); } // chiude la connessione dbconn.close(); In questo semplice esempio sono stati prelevati dalla tabella tab1 del database miodb tutti i valori del campo dato. I metodi esposti dalla classe ResultSet per la lettura dei dati si differenziano in base al tipo del campo da rappresentare. Il nome di ogni metodo è composto dal prefisso “get”, seguito dal tipo di dato che può elaborare. Metodo Tipo del campo getInt() Numerico intero getFloat() Numerico con virgola getByte() Numerico byte getlong() Numerico lungo getString() Stringa o testo getBoolean() Booleano(ver/falso) getdate() Data Per poter avanzare tra i vari record (spostarsi avanti con il cursore) resultSet espone il metodo next(), che restituisce un valore booleano che indica se il cursore è arrivato al temine della tabella. Per far questo è sufficiente creare un ciclo while(rs.next()) per scorrere senza ulteriori istruzioni la tabella generate dalla query. 11 Inserimento e modifica dei dati in un Database Nel caso si renda necessario aggiornare, inserire, modificare, o eliminare records in un database, il codice varia; l’oggetto ResultSet, non è più necessario visto che l’operazione non restituisce più un riferimento ad una tabella creata con un’istruzione select. È sufficiente richiamare il metodo executeUpdate() dell’oggetto Statement precedentemente definito, e dare come ingresso la query SQL (INSERT, UPDATE, CREATE TABLE). Questo metodo restituisce un valore intero che è uguale a 1 se tutto è stato eseguito con successo. È bene quindi effettuare un controllo sul valore restituito in modo da capire se la modifica al database sia effettivamente avvenuta. L’esempio proposto di seguito aggiunge al database un record il cui campo è contenuto in una variabile della pagina JSP, che può quindi provenire da un form o da un’elaborazione dati precedente. <html> <head> <title> Esempio di inserimento di una riga nel DataBase </title> </head> <body> <% !-- deve essere importato il package java.sql.* per eseguire le istruzioni SQL --%> <%@ page language = “java” import=”java.sql.*” %> <% int valore = 25; // valore di esempio int esito; //esito dell’aggiornamento Connection conn = null; // Carica il file di classe del driver per il ponte Odbc Class.forName(“sun.jdbc.odbc.JdbcOdbcDriver”); // crea la connessione con l’origine dari conn = DriverManager.getConnection(“jdbc:odbc:miodb”,” ”,” ”); // crea lo statement Statement st = conn.createStatement(); // esegue l’aggiornamento o l’inserimento Esito = st.executeUpdate(“INSERT INTO tab1 (dati) values (“+valore+”)”)) // se esito è uguale a 1 tutto è andato bene if (esito ==1) out.ptintln(“Inserimento eseguito correttamente”); else outprintln(“Inserimento non eseguito); // chiude la connessione rs.close(); conn.close(); %> </body> </html> È facile intuire che altre operazioni, quali l’eliminazione (DELETE), la modifica (UPDATE), ecc. vengono eseguite allo steso modo cambiando leggermente il codice ed inserendo i comandi SQL appropriati. Figura 7 - Schematizzazione degli oggetti di una connessione JDBC 12 JavaBean ed Enterprise JavaBean (EJB) Queste componenti sono elementi importantissimi per un’applicazione complessa che utilizzi tecnologie Java, non solo per quelle orientate al web. Un EJB è una classe Java che segue determinate regole imposte dalla specifica che, una volta programmato, viene posto in un application server e da esso verrà gestito secondo le regole definite. In un contesto Java “puro”, generalmente, i client di questi oggetti sono le pagine JSP e le servlet, che si appoggiano agli EJB per definire il contenuto dinamico da mostrare all’utente (es. una ricerca, un carrello di acquisti, ecc.). Questo modello di sviluppo consente a chi produce il componente server side di disinteressarsi di chi e come accederà al servizio (queste operazioni saranno svolte dall’application server). Un JavaBean ha la funzione principale di contenere e manipolare le informazioni ed è rappresentata da una classe Java con determinati requisiti: lo stato dell’istanza deve avere proprietà accessibili solo all’interno della classe stessa (visibilità privata); devono esservi metodi pubblici specifici per poter ottenere - getProperty() - e manipolare - setProperty(value) - le informazioni; il suo costruttore non deve avere argomenti; può comunicare i propri cambiamenti di stato con altre componenti mediante la generazione di eventi; l’istanza deve essere serializzabile (implementando l’interfaccia Serializable). Di seguito, è rappresentato un semplice esempio d’implementazione di un JavaBean per la raccolta delle informazioni di un utente in navigazione all’interno di una generica applicazione. La proprietà pagineViste rappresenta il numero di pagine viste dall’utente durante la navigazione; la proprietà user, invece, identifica il login dell’utente. package as.objects; /** * * @author user */ public class Canale { //VARIABILI DI ISTANZA private int id; private String nome; //COSTRUTTORE public Canale (int id, String nome){ this.id = id; this.nome = nome; } //METODI public int getId (){ return id; } public String getNome(){ return nome; } public void setId(int id) { this.id = id; } public void setNome(String nome) { this.nome = nome; } } 13 Queste componenti sono state pensate principalmente per essere manipolate attraverso applicazioni grafiche per cui sono largamente utilizzate. Attualmente hanno ottenuto un notevole successo anche in applicazioni web nei progetti di tipo enterprise. Tutte le entità dell’applicazione sono state infatti modellate come JavaBean e saranno manipolate ed utilizzate per mantenere informazioni dal modulo Client e Server. I JavaBean saranno contenuti in uno specifico package .object. Gli Enterprise JavaBean non sono altro che l’equivalente della tecnologia JavaBean in ambito enterprise ed implementano la logica di business dell’applicazione. L’introduzione di questo tipo di tecnologia nel lato server fu introdotta per risolvere i seguenti problemi: Persistenza dei Dati; Gestione delle transazioni; Controllo della concorrenza; Standard di sicurezza; Integrazione di componenti software, anche di natura diversa; Invocazione di procedure remote; Fornire servizi sul web. Vi sono tre tipi di EJB: EJB di sessione o Session EJB: la vita di questo tipo di oggetto è legata alla richiesta di utilizzo da parte del client, poiché dopo l’utilizzo viene elaborata la sua eliminazione. Per questo motivo, un Session EJB non è un elemento condiviso con altri Client ed ha, generalmente, un ciclo di vita limitato. Il suo scopo principale è quello di fornire un’interfaccia semplice per tutti i client che richiedono di accedere a determinate informazioni; una strutturazione di questo tipo impedisce che modifiche alla struttura dati di controllo comportino correzioni alle applicazioni client. In figura 4 è rappresentata la posizione di un EJB di sessione tra client e il gestore delle informazioni, mascherando il meccanismo per il recupero e la manipolazione dei dati. Figura 8 - Schema del ruolo di una Session EJB EJB di Entità o Entity EJB: forniscono la caratteristica di persistenza dei dati. Questi oggetti inglobano i dati sul lato server, come ad esempio righe di una tabella di un database o un File-System; possono essere condivisi da client diversi e sono in grado di sopportare periodi di disservizio dell’application server. Nel loro utilizzo più frequente, inglobano i dati di un database tramite oggetti Java, grazie ai quali è possibile manipolarli più agevolmente all’interno delle proprie applicazioni e senza l’utilizzo diretto di JDBC. Di norma, il client per accedere a questi Bean utilizza EJB di sessione stateless (presentati nel punto precedente), aumentando ulteriormente la stratificazione logica di queste componenti. Sia gli EJB di sessione sia di entità hanno un funzionamento sincrono, perciò il client che li invoca deve attendere la terminazione della loro elaborazione potendo, poi, continuare la propria esecuzione. 14 Figura 9 - Nello schema sono rappresentati in grigio gli entity EJB e in tratteggio i session stateless EJB EJB pilotati da messaggi o Message Driven EJB (MDB): sono gli unici EJB ad avere comportamento asincrono, grazie all’utilizzo delle specifiche JMS (Java Message Service). Il client che intende invocare queste componenti, deve essere in grado di pubblicare o accodare messaggi su una coda, i quali vengono raccolti dall’application server e forniti ad un MDB. Una volta ricevuto il messaggio, l’MDB può invocare in modo sincrono altri tipi di EJB, attendere i risultati di ritorno ed accodare un messaggio di fine elaborazione al client invocante; tutto questo con la possibilità da parte del client di proseguire la sua esecuzione. 15 Il pattern architetturale MVC Il modello più utilizzato in ambito delle applicazioni orientate al web (ma non solo) è il pattern Model-View-Controller (MVC). Questo pattern permette una maggiore strutturazione del codice, con un aumento della manutenibilità software e una suddivisione dell’applicazione in sottosistemi. Per comprendere la filosofia del modello, in figura 6, è riportata la schematizzazione delle tre componenti in cui si divide. Figura 10 - Implementazione comune del pattern MVC Le componenti sono: la vista (view) dove viene gestita la presentazione dei dati. E’ rappresentata da tutto quel codice di presentazione che permette all’utente (ad esempio tramite un browser) di operare le richieste. All’interno di questo livello lavorano sia programmatori che grafici che curano la parte estetica della presentazione; il modello (model) che rappresenta e gestisce i dati, tipicamente persistenti su database; il controllore (controller) che veicola i flussi di interazione tra vista e modello, organizzando il comportamento dell’applicazione e tracciando la navigazione con meccanismi che creano uno stato associato all’utente. Nello specifico, intercetta le richieste HTTP del client e traduce ogni singola richiesta in una specifica operazione per il model; in seguito può eseguire lui stesso l’operazione oppure delegare il compito ad un’altra componente. In ultima, seleziona la corretta vista da mostrare al client ed inserisce, eventualmente, i risultati ottenuti. 16