Autore: Paolo Picella Versione: DRAFT Breve Tutorial su J2EE I Prerequisiti 1. Conoscenza elementare di java. Per avere un introduzione a java si può consultare il libro “Thinking in Java” 1. Conoscenza del linguaggio html. II Introduzione La piattaforma J2EE permette di costruire applicazioni seguendo il principio MVC (model view controller). Tale modello si propone di separare la vista dei dati, dai dati stessi e dal controllo sui dati. Le applicazioni J2EE vengono eseguite da dei software detti application server che offrano alcune funzionalità già implementate. In questo documento trascuriamo alcuni aspetti delle funzionalità offerte da un application server j2ee e ci concentriamo sui passi fondamentali per lo sviluppo di una web application in ambiente J2EE. In particolare ci concentreremmo sui passi per la creazione della parte web dell'applicazione. II.1 Struttura dell'applicazione Consideriamo una generica applicazione che deve manipolare dei dati presenti su di un Data Base. Lo schema dei server con cui interagiremmo è il seguente: Il motivo per cui nella figura sono stati rappresentati distinti il web server, il servlet engine, ed il container ejb è che essi possono fisicamente trovarsi su macchine diverse collegate in rete. Noi per ora li considereremmo non solo sulla installati sulla stessa macchina ma facenti parte dello stesso software applicativo. la sequenza logica del funzionamento è il seguente: 1 Autore: Paolo Picella Versione: DRAFT 1) L'utente si connette al web server dell'application server. 2) Manda un richiesta POST o GET1 al web server. 3) Il web server chiama la servlet che esegue la richiesta. 4) la servlet carica l'EJB e ne esegue i metodi necessari. 5) l'EJB si connette al database agisce come richiesto sui dati. 6) la servlet crea la pagina html di risposta alla richiesta. 7) il web server rimanda la pagina al browser dell'utente. Nel seguito di questo documento analizzeremmo una applicazione di esempio minimale e descriveremmo i passi per creare l'applicazione. III Architettura software dell'applicazione di esempio L'applicazione è composta da: 1. Un EJB di cui non analizzeremmo in profondità il codice ma vedremmo solamente come interfacciarsi con esso. 2. Una servlet con alcune helper class (Classi di utilità) L'architettura è rappresentata nella seguente figura: Analizziamo l'architettura rappresentata in fugura: 1 I metodi post e get sono standard definiti dalla w3c. Ref: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html 2 Autore: Paolo Picella Versione: DRAFT La richiesta dell'utente arriva al web server: caso in cui la richiesta è di una pagina statica: il web server carica la pagina statica e la invia all'utente. Caso in cui la viene richiesta una pagina dinamica: il web server chiama la servlet la servlet chiede al bean di effettuare le operazioni richieste sui dati la servlet tramite le API2 Jakarta-Velocity3 prende dei template html e ne valorizza i campi. La servlet restituisce le pagine così create al web server il web server invia i dati all'utente IV Class Diagram dell'applicazione Il class diagram illustra come viene organizzata l'applicazione in termini di classi ed i legami tra le le varie classi dell'applicazione. Le classi normalmente vengono organizzate in package4 che assolvono a due funzioni: 1. raggruppano logicamente le classi 2. evitano che vi siano dei conflitti nei nomi delle classi Un class diagram normalmente è rappresentato utilizzando gli standard UML. IV.1 Definizione dei package delle classi a Classi di utilità Comuni ad EJB e Servlet Come abbiamo detto avremmo delle classi che vengono utilizzate sia dagli EJB che dalle servlet. dato che concettualmente gli ejb e le servlet possono girare in ambienti distinti è opportuno raggruppare le classi di utilità comuni in modo da poterle facilmente includerle sia nella distribuzione degli EJB che in quella delle servlet se vuole sfruttare questa opportunità. Inoltre quando si usa una classe all'interno di un altra la si deve importare l'aver raggruppato le classi di utilità comuni ad EJB e SERVLET in un unico package permette di importarle facilmente senza fare errori basta inserire con un solo import. Nelle classi di utilità comuni includeremmo: 1. I value object: Si usa chiamare Value Object una classe che è adibita a contenere dei dati, tale classe fornisce i metodi per inserire i dati all'interno di essa. Tali metodi sono deputati a 2 API, Application Programming Interface, Librerie di Classi che forniscono delle utilità 3La documentazione delle API Jakarta-Velocity è reperibile all'indirizzo: http://jakarta.apache.org/velocity/user-guide.html 4Ref: http://java.sun.com/docs/books/tutorial/ e 'Thinking in java' 3 Autore: Paolo Picella Versione: DRAFT controllare che il dato inserito sia consistente con le regole che devono essere applicate al dato. Es: il dato nome è una stringa composta da soli caratteri alfabetici maiuscoli e minuscoli e non può avere lungezza superiore a 24 caratteri. Il metodo di inserimento (per convenzione si chiama setNomeVariabile(Tipo_variabile variabile)) setNome(String nome) si preoccupa di verificare che la stringa passata in input sia di 24 caratteri alfabetici. 2. Una classe contenente le costanti 3. Una classe che contiene le eccezioni4 del nostro applicativo. Il package in cui saranno messe queste classi è (questo significa che nel codice delle classi la prima istruzione è: package com.apat.ccon.common): com.apat.ccon.common b Classi degli EJB Un enterprise java bean è composto come minimo da una classe e due interfacce: La classe che contiene il codice dell'EJB vero e propri. La HOME Interface, che contiene i metodi per creare, distruggere etc. L'ejb. La REMOTE Interface, che è l'interfaccia usata dal client per accedere ai metodi dell'ejb. Le servlet utilizzeranno solo le interfacce HOME e REMOTE dell'EJB. Per convenzione chiameremmo le classi secondo la seguente convenzione: NomeBeanSLEjb è l'EJB vero e proprio NomeBeanSL è la REMOTE interface NomeBeanSLHome è la HOME Interface Insieme a queste classi metteremo una classe DAO (Database Access Object) che si occupera di interfacciarsi con il database. Il package in cui saranno messe queste classi è (questo significa che nel codice delle classi la prima istruzione è: package com.apat.ccon.ejb): com.apat.ccon.ejb c Classi delle servlets In questo gruppo vi sono tutte le servlet chiamate dall'interfaccia utente più le due seguenti classi: La Classe Proxy: Questa classe si occupa di prendere la home interface dell'EJB, di creare tramite la HOME interface le REMOTE interface dell'EJB, e di chiamare i metodi sull EJB. La Classe Facade: 4 Autore: Paolo Picella Versione: DRAFT Crea un istanza Static del Proxy in modo da non dover predere la remote per ogni connessione ma di farlo una sola volta ed espone i metodi del proxy alle servlet. Il package in cui saranno messe queste classi è (questo significa che nel codice delle classi la prima istruzione è: package com.apat.ccon.web): com.apat.ccon.web nella nostra applicazione è presente un super classe ulteriore di utilità per le servlet . Le servlet che vorranno usufruire dei settaggi standard e dei metodi di utilità implementati in questa classe dovranno estenderla. La Classe CCOONServlet: Questa è una classe di utilità include i metodi comiuni a tutte le servlet come i metodi di inizializzazione e di gestione delle eccezioni. V Breve Introduzione Alle Applicazioni J2EE Una applicazione J2EE è una applicazione sviluppata seguendo gli standard di questa tecnologia, il codice sviluppato non è auto consistente ma per essere utilizzato deve essere inserito in un application server che risponde alle specifiche J2EE. Tale server si occupa di caricare l'applicazione e la rende utilizzabile. V.1 L'archivio ear Una applicazione J2EE deve essere contenuta in un archivio con estensione .ear. All'interno di questo file vi è un archivio con estensione .jar, un archivio con estensione .war, una directory META-INF contenente il file application.xml come descritto nella tabella seguente. Contenuto dell'archivio .ear path/ nome file path/ nome file path/ nome file descrizione Archivio.jar Archivio l'EJB Archivio.war Archivio contenente la Web Application META-INF Derictory contenente il descrittore dell'applicazione application.xml contenente File XML descrittore dell'applicazione. Tale file è usato dall'application server per sapere di cosa è composta l'applicazione 5 Autore: Paolo Picella Versione: DRAFT Esempio di file descrittore: <?xml version="1.0" encoding="ISO8859_1"?> <!DOCTYPE application PUBLIC '-//Sun Microsystems, Inc.//DTD J2EE Application 1.2//EN' 'http://java.sun.com/j2ee/dtds/application_1_2.dtd'> <application> <display-name>CCOON</display-name> <description>EJB del Sistema Centro di Coordinamento Nazionale</description> <module> <ejb>ccoon.jar</ejb> </module> <module> <web> <web-uri>ccoon.war</web-uri> <context-root>CCOON</context-root> </web> </module> </application> V.2 L'archivio jar L'archivio con estenzione .jar contiene tutte le informazioni necessarie all'application server per 'creare' l'EJB in esso sono compresi i seguenti file: 1. le classi java che compongono gli ejb contenuti nell'archivio, quindi tutte le loro remote ed home interface, tutti gli ejb veri e propri e tutte le loro helper class (DAO e quantaltro) 2. un descrittore ejb-jar.xml posto nella directory META-INF che descrive all'application server gli ejb contenuti nell'archivio 3. un decrittore opzionale che imposta le opzioni specifiche dell'application server Esempio di un descrittore: <?xml version="1.0"?> <!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 1.1//EN' 'http://java.sun.com/j2ee/dtds/ejb-jar_1_1.dtd'> <ejb-jar> <description>EJB del sistema Centro di coordinamento nazionale</description> <display-name>CCOON System EJB</display-name> <enterprise-beans> <session> <ejb-name>CCOONSL</ejb-name> 6 Autore: Paolo Picella Versione: DRAFT <home>com.apat.ccoon.ejb.CCOONSLHome</home> <remote>com.apat.ccoon.ejb.CCOONSL</remote> <ejb-class>com.apat.ccoon.ejb.CCOONSLEJB</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> </session> </enterprise-beans> <assembly-descriptor> <container-transaction> <method> <ejb-name>CCOONSL</ejb-name> <method-name>*</method-name> </method> <trans-attribute>Required</trans-attribute> </container-transaction> </assembly-descriptor> </ejb-jar> V.3 L'archivio war L'archivio con estenzione .war contiene tutte le informazioni necessarie all'application server per 'creare' la Web Application in esso sono compresi i seguenti file: 1. tutte le pagine statiche html, i template e le classi degli applet usati nella Web Application. 2. Una directory WB-INF contenente: un file web.xml che descrive all'application server le servlet della web application una directory classes contenente tutte le classi delle nostre servlet e le loro helper classes (Proxy, Facade e quantaltro) esempio di un descrittore web.xml: <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"> Web Application <web-app> <display-name>CCOON</display-name> <servlet> <servlet-name>AddCCNServlet</servlet-name> <servlet-class>com.apat.ccoon.web.AddCCNServlet</servlet-class> <init-param> <param-name>template_path</param-name> <param-value>/opt/Programmi/jboss-3.0.0/server/default/template</paramvalue> </init-param> </servlet> 7 Autore: Paolo Picella Versione: DRAFT <servlet-mapping> <servlet-name>AddCCNServlet</servlet-name> <url-pattern>/AddCCNServlet</url-pattern> </servlet-mapping> </web-app> VI Applicazione di esempio La nostra applicazione di esempio che chiameremo tutorial avrà bisogno: di un database che chiameremo tutorial con almeno una tabella al suo interno di un application server J2EE (nell'esempio ci riferiremmo a jboss 3.0.x) di un DataSource connesso al database tutorial configurato sull'application server come detto in precedenza non ci occuperemmo di analizzare il codice del bean ma solo della parte della Web application. VI.1 Creazione del database e del datasource In questo paragrafo viene descritto come creare il database ed il datasource necessari a far funzionare l'esempio. Le istruzioni si riferiscono alla creazione del database su postgres 7.2 ed alla creazione del datasource su jboss 3.0.4. a Creazione del database Il database dell'applicazione di esempio si chiama ccoondb e contiene la tabella ccn. TABELLA CCN Nome del campo Tipo Descrizione id serial Chiave primaria dell centro di controllo Nome Varchar(24) Nome del centro di controllo Localita Varchar(24) Località in cui è situato il centro di controllo Rete Varchar(24) Nome della appartenenza created timestamp Timestamp di quando è stato creato il record sul db last_update timestamp Timestamp di quando è il ccn si è collegato per aggiornare i dati latitudine Float8 longitudine 8 rete di Autore: Paolo Picella Versione: DRAFT TABELLA CCN longitudine float8 latitudine Qui di seguito sono riportati i passi necessari alla creazione del database, viene assunto che postgres sia inizializzato e che il demone sia avviato. Dalla shell come utente postgres eseguire i comando: createdb ccoondb createlang plpgsql ccoondb psql ccoondb in questo modo si è creato il database ccoondb e si è entrati nel database ccoon conclient sql di postgres. A questo punto bisogna creare l'utente ccoon_admin con password puzzola per accedere al db con il seguente comando. create user ccoon_admin with password 'puzzola' createuser; \q uscire dalla shell dell'utente postgres l'utente cosi creato è l'owner del database ccoon e ha su di esso il massimo delle autorizzazioni. Si può scegliere di utilizzare per la connessione un utente avente solo i diritti necessari al funzionamento dell'applicazione ma questo va oltre lo scopo di questo documento. Bisogna quindi eseguire gli script sql per creare il data model e le stored procedure per fare ciò con la propria utenza. Digitare i seguenti comandi: psql ccoondb -U ccoon_admin \i [path di dove si estratta l'applicazione di esempio]/SQL/creteDB.sql \i [path di dove si estratta l'applicazione di esempio]/SQL/creteFunc.sql \q b Creazione del datasource Copiare i driver jdbc di postgres, pgjdbc2.jar nella directory: [path dell'installazione di jboss]/server/default/lib Copiare il file: [path di dove si estratta l'applicazione di esempio]/ccoon-pg-service.xml nella directory: [path dell'installazione di jboss]/server/default/deploy c Creazione della directory comune dei template Poiché le Velocity Servlet lavorano con un Singleton il path di dove sono messi i template di tutte le applicazioni deve essere comune. Creiamo quindi una directory per i template: 9 Autore: Paolo Picella Versione: DRAFT mkdir [path dell'installazione di jboss]/server/default/template Per comunicare alla servlet addCCNServlet quale è la directory comune dei template bisogna metterela nel file web.xml nel segente modo: <servlet> <servlet-name>AddCCNServlet</servlet-name> <servlet-class>com.apat.ccoon.web.AddCCNServlet</servlet-class> <init-param> <param-name>template_path</param-name> <param-value>{path dell'installazione di jboss]/server/default/template</param-value> </init-param> </servlet> Le righe evidenziate in rosso sono quelle che passano il parametro alla servlet. in questa directory creiamo una directory CCOON che contiene i template della nostra applicazione e quindi una direcory template. mkdir [path dell'installazione di jboss]/server/default/template/CCOON mkdir [path dell'installazione di jboss]/server/default/template/CCOON/template Copiamo quindi in questa directory i template dell'applicazione. VI.2 Struttura dei package della applicazione Le servlet saranno nel package com.apat.ccon.web, le classi di utilità nel package com.apat.ccon.common, le classi dell'ejb nel package com.apat.ccon.ejb. Nei Prossimi paragrafi analizzeremmo i class diagram dell'applicazione realizzati con lo standard UML. Tali diagrammi servono a indicare come sono legate le classi e le interfaccie tra loro (legami di estenzione e di uso tra le classi) e i metodi che esse espongono. a Class Diagram dell'EJB Il Class Diagram di figura che rappresenta la struttura degli ejb dell'applicazione vi sono due classi: 1. CCOONSLEJB è un SessionBean e quindi vi saranno anche la Remote Interface e la Home Interface. La Remote Interface CCOONSL espone i metodi addCCN , searchCCN e deleteCCN. La Home Interface espone il metodo ejbCreate. La classe CCOONSLEJB ha una un oggetto di tipo CCOONDAO. 2. CCOONDAO è una classe che si occupa di gestire l'accesso al database (da cui il nome DAO Database Access Object) ed espone i metodi addCCN per aggiungere un Centro di Controllo Nazionale, searchCCN per cercare un Centro di Controllo Nazionale, deleteCNN per cancellare un Centro di Controllo Nazionale. 10 Autore: Paolo Picella Versione: DRAFT Figura 1 Class Diagram dell'EJB b Class Diagram della web application In Figura che rappresenta il Class Diagram della Web Application sono presenti quattro classi: CCOONServlet è una classe che implementa i metodi di utilità comuni a tutte le servlet. Nelnostro caso implementa per tutte le servlet i metodi init , loadConfiguration e handleApplicationException che gestisce glie errori applicativi. AddCCNServlet: la classe estende la classe CCOONServlet da cui eredita tutti i metodi e nel metodo handleRequest gestisce la richiesta effettuata dal client. CCOONFacade: la classe si occupa di creare un ogetto CCOONProxy statico (questo è fatto per ottimizzare le prestazioni dell'applicativo) e ne chiama i metodi. CCOONProxy. La classe si occupa di interfacciarsi con l'EJB e di chiamare il metodo richiesto dal client. il metodo getCCOONSL si occupa di creare la connessione con il bean, quindi fa il lookup dell'EJB, prende la Home Interface crea il Bean e fa il lookup della remote interface. 11 Autore: Paolo Picella Versione: DRAFT Figura 2 Class Diagram Della Web Application c Class Diagram delle classi di utilità comuni Figura 3 Class Diagram Delle Classi Di Utilità Comuni VI.3 Creazione della della funzionalità di aggiunta di un CCN Vediamo adesso come creare la funzionalità di aggiunta di un CCN. Tale funzionalità deve inserire un nuovo CCN (Centro di Controllo), i dati che identificano il CCN sono: id: identificativo univoco del CCN sul db e non è assegnato dall'utente name: il nome del CCN rete: rete a cui il CCN appartiene 12 Autore: Paolo Picella Versione: DRAFT località: località dove è situato il CCN latitudine: latitudine del CCN longitudine: longitudine del CCN Se l'inserimento è andato a buon fine la funzionalità dovrà visualizzare i dati immessi e l'id del CCN inserito, se si è verificato un errore dovrà ritornare un messaggio di errore all'utente. Per realizzare tale funzionalità bisogna creare: La pagina html per l'inserimento dei dati. La servlet: addCCNServlet Il template per la visualizzazione dei dati inseriti. Aggiungere la servlet nel file web.xml che descrive la web application. a Creazione della pagina html per l'inserimento dei dati. Per passare i dati ad un server bisogna creare una pagina html con all'interno un oggetto form che contenga i campi da inviare alla servlet. Qui di seguito riportiamo il codice della pagina commentato contenuto nel file dell'applicazione di esempio /build/web/html/ccn_from.html. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> <html> <head> <title>CCNForm</title> </head> <body> <!-- commento: tag di apertura di una form che all pressione del bottone submit manda i campi definiti al suo interno alla servlet /CCOON/AddCCNServlet --> <form action="/CCOON/AddCCNServlet" method="POST"> <table width=300 cellspacing=2 border=0 cellpadding=2> <th colspan=2 bgcolor="lightGray"><font color="#c50000">Form di inserimento dati di un CCN</font></th> <tr align="left " valign="center"> <td align="left">nome ccn</td> <!-- commento: campo name da passare alla sevlet --> <td align="left"><input type="text" name="name" size=24 maxlength=24></td> </tr> <tr align="left " valign="center"> <td align="left">località ccn</td> <!-- commento: campo località da passare alla sevlet --> <td align="left"><input type="text" name="localita" size=24 maxlength=24></td> </tr> 13 Autore: Paolo Picella Versione: DRAFT <tr align="center " valign="center"> <td align="left">rete ccn</td> <!-- commento: campo rete da passare alla sevlet --> <td align="left"><input type="text" name="rete" size=24 maxlength=24></td> </tr> <tr align="left" valign="center"> <td align="left">latitudine ccn</td> <!-- commento: campo latitudine da passare alla sevlet --> <td align="left"><input type="text" name="latitudine" size=24 maxlength=24></td> </tr> <tr align="left " valign="center"> <td align="left">longitudine ccn</td> <!-- commento: campo longitudine da passare alla sevlet --> <td align="left"><input type="text" name="longitudine" size=24 maxlength=24></td> </tr> <tr align="left " valign="center"> <td align="left">&nbsp;</td> <!-- commento: bottone di tipo submit che invia i campi alla sevlet --> <td align="left"><input type="submit" name="submit" value="invia"></td> </tr> </table> </form> </body> </html> b Creazione del template di visualizzazione dei campi immessi A questo punto bisognerà creare un template per la visualizzazione dei dati immessi nel database. Un template per velocity permette di utilizzare i valori passati da una velocity servlet. Noi passeremmo un oggetto di tipo CCNVO che contiene i dati del CCN appena inserito sul db, e chiameremmo i metodi che restituiscono i dati contenuti nel CCN (metodi che iniziano con get). L'oggetto lo passeremmo con il nome ccnVO. Qui di seguito è riportato il codice del template contenuto nel file dell'applicazione di esempio build/template/manage_ccn.vm <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"> <html> <head> <title>manage CCN</title> </head> <body> 14 Autore: Paolo Picella Versione: DRAFT <table width=300> <!-- commento: qui di sotto diciamo di inserire il valore ritornato metodo getName() dell'ogetto ccnVO --> dal <th colspan=2 bgcolor="lightGray"><font color="#c50000">Dati del Centro di controllo $ccnVO.getName()</font></th> <tr align="center " valign="center"> <td width="90%"> <table> <tr> <td>Id</td> <!-- commento: qui di sotto diciamo di inserire il valore ritornato dal metodo getId() dell'ogetto ccnVO --> <td>$ccnVO.getId()</td> </tr> <tr> <td>Località</td> <!-- commento: qui di sotto diciamo di inserire il valore ritornato metodo getLocalità() dell'ogetto ccnVO --> dal <td>$ccnVO.getLocalita()</td> </tr> <tr> <td>Rete</td> <!-- commento: qui di sotto diciamo di inserire il valore ritornato metodo getRete() dell'ogetto ccnVO --> dal <td>$ccnVO.getRete()</td> </tr> <tr> <td>Longitudine</td> <!-- commento: qui di sotto diciamo di inserire il valore ritornato metodo getLongitudine() dell'ogetto ccnVO --> dal <td>$ccnVO.getLongitudine()</td> </tr> <tr> <td>Latitudine</td> <!-- commento: qui di sotto diciamo di inserire il valore ritornato metodo getLatitudine () dell'ogetto ccnVO --> dal <td>$ccnVO.getLatitudine()</td> </tr> </table> </td> <td bgcolor="lightGray"> <table bgcolor="lightGray"> <tr> <td><input type="submit" disabled name="Invia" value="Edit" ></td> 15 Autore: Paolo Picella Versione: DRAFT </tr> <tr> <td><input type="submit" disabled name="Invia" value="Delete" size=10></td> </tr> <tr> <td><input type="submit" disabled name="Invia" value="Manage SM" size=10></td> </tr> </table> </td> </tr> </table> </body> </html> c Creazione della servlet AddCCNServlet Quando il bottone submit verra premuto dall'utente verra invocato il metodo handleRequest della servlet AddCCNServlet . La servlet dovrà estendere la classe CCOONServlet per ereditarne le funzionalità. La servlet dovrà prendere i campi inviati dall'utente, i parametri sono contenuti nell'oggetto request di tipo HttpServletRequest che viene passato come parametro al metodo handleRequest della servlet invocando su di esso il metodo getParameter(nomeParametro) il metodo getParameter ritornerà una stringa (più precisamente un oggetto di tipo String) contenente il valore del parametro se il parametro esiste, null se il parametro non esiste. Nel nostro caso ad esempio per prendere il parametro name userememmo l'istruzione request.getParameter(“name”). Dovremmo quindi creare un oggetto di tipo CCNVO necessario come input al metodo addCCN(CCNVO ccnVO) del CCOONFacade e valorizzarne i campi. Il CCNVO si occupa di controllare che il formato dei dati inseriti sia corretto. Una volta valorizzato il ccnVO si chiamerà il metodo addCCN della classe CCOONFacade con a parametro il l'ogetto CCNVO da noi valorizzato. Tale metodo deve stare dentro un blocco try-catch perché lancia delle eccezioni. Nei blocchi catch vengono gestite le eccezioni e viene chiamato il metodo handleApplication exception ereditato dalla classe CCOONServlet, per la visualizzazione dell'errore all'utente. Qui di seguito riportiamo il codice commentato della servlet dell'applicazione di esempio contenuta nel file: com/apat/ccoon/web/AddCCNServlet. /* * APAT */ package com.apat.ccoon.web; 16 Autore: Paolo Picella Versione: DRAFT import javax.servlet.http.*; import javax.servlet.*; import java.util.*; import java.io.*; import com.apat.ccoon.common.*; // Import necessari ad utilizzare il parser velocity e la classe velocity servlet import org.apache.velocity.servlet.VelocityServlet; import org.apache.velocity.context.Context; import org.apache.velocity.Template; import org.apache.velocity.app.Velocity; import org.apache.velocity.exception.ResourceNotFoundException; import org.apache.velocity.exception.ParseErrorException; import org.apache.velocity.VelocityContext; /** * Description of the Class: La servlet estende la CCOONServlet e ne eredita * tutti richiesta * i metodi. deve fare l'override del metodo in cui gestisce la fatta dall'utente * * @author Paolo Picella * @created 8 dicembre 2002 * @Log $Log */ public class AddCCNServlet extends CCOONServlet { /** * Description of the Method: metodo che gestisce le richieste POST e GET * effettuate dall'utente * * @param request Vedi documentazione java * @param response Vedi documentazione java * @param ctxV Velocity Context * @return eseguita Template contenente il risultato dell'operazione */ public Template handleRequest(HttpServletRequest request, HttpServletResponse response, Context ctxV) { // Creo un CCNVO vuoto in cui inserisco i parametri CCNVO ccnVO = new CCNVO(); // definisco il template con cui visualizzare i parametri 17 Autore: Paolo Picella Versione: DRAFT String templateName = "CCOON/template/manage_ccn.vm"; // inizializzo il messaggio di stato String message = "Successo"; // inizializzo il Velocity template Template outty = null; try { // inserisco i parametri nel VO ccnVO.setName(request.getParameter("name")); ccnVO.setLocalita(request.getParameter("localita")); ccnVO.setRete(request.getParameter("rete")); ccnVO.setLongitudine(request.getParameter("longitudine")); ccnVO.setLatitudine(request.getParameter("latitudine")); // chiamo il metodo sul facade che mi inserisce i dati nel DB ccnVO = CCOONFacade.addCCN(ccnVO); // inserisco gli oggetti nel contesto Velocity ctxV.put("ccnVO", ccnVO); // Elaboro il template outty = getTemplate(templateName); } // Gestisco le eccezioni applicative catch (CCOONException ccoone) { outty = handleApplicationException(ctxV, ccoone); System.out.println(message); } // Gestisco le eccezioni generate nel parsing del template catch (ParseErrorException pee) { CCOONException CCOONConst.ES_TEMPL + pee); ccoone = new CCOONException(CCOONConst.E_TEMPL, outty = handleApplicationException(ctxV, ccoone); System.out.println(CCOONConst.ES_TEMPL + pee); } // Gestisco le eccezioni generate caricamento del template catch (ResourceNotFoundException rnfe) { CCOONException ccoone CCOONConst.ES_TEMPL + rnfe); = new CCOONException(CCOONConst.E_TEMPL, outty = handleApplicationException(ctxV, ccoone); System.out.println("AddCCNServlet : template not found " + rnfe); } //gestisco tutti gli altri tipi di eccezione catch (Exception e) { System.out.println("Error " + e); } // ritorno il template 18 Autore: Paolo Picella Versione: DRAFT return outty; } } d Inserimento della servlet nel file di configurazione Per inserire la servlet bisogna editare il file di configurazione build/web/WEB-INF/web.xml. In tale file bisogna inserire le linee di codice XML evidenziate in giallo nel listato qui di seguito riportato: <?xml version="1.0"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"> Web Application <web-app> <display-name>CCOON</display-name> <servlet> <servlet-name>AddCCNServlet</servlet-name> <servlet-class>com.apat.ccoon.web.AddCCNServlet</servlet-class> <init-param> <param-name>template_path</param-name> <param-value>[path all'installazione di jboss]/server/default/template</param-value> </init-param> </servlet> <servlet> <servlet-name>SearchCCNServlet</servlet-name> <servlet-class>com.apat.ccoon.web.SearchCCNServlet</servlet-class> <init-param> <param-name>template_path</param-name> <param-value>[path all'installazione di jboss]/server/default/template</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>AddCCNServlet</servlet-name> <url-pattern>/AddCCNServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>SearchCCNServlet</servlet-name> <url-pattern>/SearchCCNServlet</url-pattern> </servlet-mapping> </web-app> Nel tag servlet si definisce il nome che identifica la servlet, la classe che contiene il codice della servlet,i parametri da passare alla servlet. Come si può vedere noi passiamo un parametro template_path che contiene il path di dove sono installati i template. Nel tag <servlet-mapping> diamo l'URI della servlet. 19 Autore: Paolo Picella Versione: DRAFT VII Procedure di build, deploy ed installazione dell'applicazione di esempio. Le procedure di compilazione e di build sono state create con ant per eseguirle è necessario quindi scaricare ant dal sito http://ant.apache.org/ . Per compilare l'applicazione bisogna eseguire dalla directory Tutorila-EJB il comando: ant compilaWeb Per creare il file ear che contiene l'applicazione bisogna eseguire dalla directory Tutorila-EJB il comando: ant deploy per installare l'applicazione bisogna copiare il file ccoon.ear nella direcotry: [path di dove è installato Jboss]/server/default/deploy. VIII Riferimenti Jakarta Velocity - http://jakarta.apache.org/velocity/user-guide.html Java Servlet - http://java.sun.com/j2ee/tutorial/1_3-fcs/doc/Servlets.html ant http://ant.apache.org/ Sun Java2EE Tutorial http://java.sun.com/j2ee/tutorial/1_3-fcs/index.html Sun Java2SE Tutorial http://java.sun.com/docs/books/tutorial/index.html Editor Java Free http://www.jedit.org/ Thinking in Java 2nd edition http://www.planetpdf.com/codecuts/pdfs/eckel/TIJ2.zip Jboss Java2EE Application Server http://www.jboss.org/ 20