Tecnologie lato Server: Servlet Stefano Clemente [email protected] © 2005 Stefano Clemente I lucidi sono in parte realizzati con materiale tratto dal libro di testo adottato tradotto in italiano: © 2002 Prentice Hall H. M. Deitel, P. J. Deitel, T. R. Nieto Internet & World Wide Web – How To Program (Second Edition) Riferimenti bibliografici • H. M. Deitel, P. J. Deitel, T. R. Nieto Internet & World Wide Web – How To Program (Second Edition) ed. Prentice Hall 2002 Capitolo 30 • http://java.sun.com/developer/onlineTra ining/Servlets/Fundamentals/ • http://jakarta.apache.org 29 Novembre 2005 Stefano Clemente 2 Introduzione • Java permette lo sviluppo di applicazioni − basate su Internet − basate su Web • Java permette − lo sviluppo di applicazioni multithreaded − permette ai programmi di collaborare con programmi in esecuzione su altri computer • La comunicazione tra client e server prevede che − il client richiede che il server esegua una qualche azione − il server esegue l’azione e fornisce una risposta al client • Questo tipo di comunicazione è alla base di − Servlet − Java Server Pages (JSP) 29 Novembre 2005 Stefano Clemente 3 Introduzione • Servlet − estendono le funzionalità di un server − le classi e le interfacce per la loro definizione sono fornite dai package • javax.servlet • javax.servlet.http • JSP − permettono, attraverso una sintassi particolare, di scrivere pagine che contengono le funzionalità Java e l’inserimento di scriptlet direttamente nella pagina − le classi e le interfacce per la loro definizione sono fornite dai package • javax.servlet.jsp • javax.servlet.tagext che estendono le funzionalità delle servlet alle JSP 29 Novembre 2005 Stefano Clemente 4 Introduzione • Le Servlet sono utili nelle soluzioni basate su web per − − − − rendere sicuri gli accessi ai siti interagire con i DB generare XHTML in modo dinamico e personalizzato mantenere le informazioni sulle sessioni dei client • Per molti sviluppatori le Servlet sono la soluzione più appropriata per le applicazioni su DB che comunicano con thin-client • Lo sviluppo delle specifiche delle Servlet e delle JSP è dettato da Sun Microsystems • L’implementazione di riferimento di questi due standard è compito di Apache Software Foundation (www.apache.org) come parte del Jakarta Project (jakarta.apache.org) − Lo scopo di Jakarta Project è quello di fornire soluzioni server di qualità basate su piattaforma Java e che siano sviluppate in modo aperto e cooperativo • Jakarta Project prevede diversi sottoprogetti tra i quali Tomcat, l’implementazione ufficiale degli standard Servlet e JSP 29 Novembre 2005 Stefano Clemente 5 Servlet o JSP? • JSP è un’estensione della tecnologia servlet • Le JSP sono usate quando la maggior parte del contenuto inviato al client è testo statico e XHTML mentre solo una piccola parte è generato dinamicamente usando Java • Le Servlet sono usate invece quando solo una piccola parte di XHTML inviato al client è statica − alcune Servlet non producono contenuti − le Servlet eseguono dei compiti per conto del client e invocano altre Servlet o JSP per produrre delle risposte • Nella maggior parte dei casi Servlet e JSP sono tecnologie intercambiabili • Un server che esegue delle Servlet è detto anche Servlet Container o Servlet Engine 29 Novembre 2005 Stefano Clemente 6 Servlet: interfaccia e ciclo di vita • L’API Servlet definisce l’interfaccia tra server e Servlet • Questa API è un package estensione standard di JDK in javax − package javax.servlet − package javax.servlet.http • Tutte le Servlet devono implementare l’interfaccia Servlet del package javax.servlet (javax.servlet.Servlet) − i metodi dell’interfaccia Servlet sono invocati in modo automatico dal server sul quale la Servlet è installata • L’interfaccia dispone di cinque metodi − − − − − void init( ServletConfig config ) ServletConfig getServletConfig() String getServletInfo() void service( ServletRequest req, ServletResponse res ) void destroy() 29 Novembre 2005 Stefano Clemente 7 Servlet: interfaccia e ciclo di vita • void init(ServletConfig config) − È invocato in modo automatico per inizializzare la Servlet; l’argomento ServletConfig è passato dal Servlet Container che esegue la Servlet • ServletConfig getServletConfig() − Restituisce un oggetto che implementa l’interfaccia ServletConfig per permettere l’accesso alle informazioni sulla configurazione della Servlet • Parametri di inizializzazione • ServletContext – permette alla Servlet di accedere all’ambiente nel quale viene eseguita, vale a dire l’ambiente del Servlet Container • String getServletInfo() − Definito dal programmatore della Servlet per restituire informazioni sulla stessa Servlet (autore, versione, ecc) • void service(ServletRequest req, ServletResponse res) − Metodo invocato dal Servlet Container per rispondere a una richiesta del client • void destroy() − Metodo invocato dal Servlet Container alla fine dell’esecuzione della Servlet, con il conseguente rilascio di tutte le risorse utilizzate dalla Servlet (file, connessioni verso i DB) 29 Novembre 2005 Stefano Clemente 8 Servlet: interfaccia e ciclo di vita • Il ciclo di vita della Servlet ha inizio quando il Servlet Container carica la Servlet in memoria in conseguenza della prima richiesta che un client fa alla Servlet • Il ciclo di vita è scandito dall’invocazione dei tre metodi − init • metodo invocato dal Servlet Container prima che la Servlet possa gestire la prima richiesta ricevuta dal client • dopo l’esecuzione del metodo init la Servlet sarà in grado di rispondere alla sua prima richiesta − service • gestore delle richieste: riceve la richiesta, la elabora e invia la risposta al client • è invocato una sola volta per ogni richiesta e tipicamente una nuova richiesta comporta la creazione da parte del Servlet Container di un nuovo thread in cui il metodo service viene eseguito − destroy • quando il Servlet Container termina l’esecuzione della Servlet, invoca questo metodo per rilasciare le risorse che la Servlet aveva acquisito per la sua esecuzione 29 Novembre 2005 Stefano Clemente 9 Servlet: interfaccia e ciclo di vita • I package per le Servlet definiscono due classi abstract per l’implementazione dell’interfaccia Servlet − la classe GenericServlet appartenente al package javax.servlet − la classe HttpServlet appartenente al package javax.servlet.http • Queste classi forniscono un’implementazione di default dei metodi di Servlet • La maggior parte delle Servlet estendono queste classi e ridefinendo alcuni o tutti i metodi (override) • Gli esempi che verranno trattati saranno estensioni della classe HttpServlet 29 Novembre 2005 Stefano Clemente 10 La classe HttpServlet • Le Servlet basate sul web estendono la classe HttpServlet • La classe HttpServlet riscrive il metodo service per riconoscere le tipiche richieste (GET e POST) provenienti da un browser e a tal fine definisce i metodi − doGet − doPost • Quando una richiesta arriva al server viene invocato il metodo service, il quale − individua il tipo di richiesta − invoca il metodo appropriato per la gestione della richiesta • Per interagire con il client doGet e doPost ricevono − un oggetto HttpServletRequest come primo argomento, per accedere ai dati che il client ha passato con la richiesta − un oggetto HttpServletResponse come secondo argomento che permette la restituzione al client della risposta risultato dell’esecuzione della Servlet 29 Novembre 2005 Stefano Clemente 11 La classe HttpServlet • Esistono anche altri metodi in HttpServlet, e tutti ricevono come argomenti HttpServletRequest e HttpServletResponse − doDelete – Relativa al metodo delete del protocollo HTTP, consente la cancellazione di un file dal server (non sempre disponibile sui web server) − doOptions – Relativa al metodo options del protocollo HTTP, consente al client di conoscere le opzioni disponibili sul server (versione HTTP e metodi supportati) − doPut – Relativa al metodo put del protocollo HTTP, consente di memorizzare un file sul file system del server (non sempre disponibile sui server) − doTrace – Relativa al metodo trace del protocollo HTTP, consente di eseguire il debug 29 Novembre 2005 Stefano Clemente 12 L’interfaccia HttpServletRequest • Il web server che esegue la Servlet crea un oggetto HttpServletRequest ad ogni richiesta e lo passa al metodo service, il quale, a sua volta, lo passa alla doGet o alla doPost • L’oggetto HttpServletRequest contiene la richiesta del client • Esistono diversi metodi che consentono alla Servlet di eseguire la richiesta del client − alcuni di questi sono derivati dall’interfaccia ServletRequest che HttpServletRequest estende 29 Novembre 2005 Stefano Clemente 13 L’interfaccia HttpServletRequest • String getParameter( String name ) − estrae il valore del parametro name inviato alla Servlet con una get o una post • Enumeration getParameterNames() − restituisce il nome di tutti i parametri inviati alla Servlet con una post • String[] getParameterValues( String name ) − restituisce tutti i valori di un parametro con più valori • Cookie[] getCookies() − restituisce un array di oggetti Cookie che il server ha memorizzato sul client per poterlo identificare univocamente • HttpSession getSession( boolean create ) − restituisce un oggetto HttpSession associato alla sessione del client con il quale il server può identificare univocamente il client; l’oggetto viene creato se • l’argomento create vale true • non esiste già un oggetto HttpSession per quel client 29 Novembre 2005 Stefano Clemente 14 L’interfaccia HttpServletResponse • Il web server che esegue la Servlet crea un oggetto HttpServletResponse ad ogni richiesta e lo passa al metodo service, il quale, a sua volta, lo passa alla doGet o alla doPost • L’oggetto HttpServletRequest permette alla Servlet di rispondere al client • Esistono diversi metodi che consentono alla Servlet di rispondere al client − alcuni di questi sono derivati dall’interfaccia ServletResponse che HttpServletResponse estende 29 Novembre 2005 Stefano Clemente 15 L’interfaccia HttpServletResponse • void addCookie( Cookie cookie ) − aggiunge un cookie all’intestazione della risposta • ServletOutputStream getOutputStream() − flusso di dati in byte che permette di inviare dati binari al client • PrintWriter getWriter − flusso di dati in caratteri che permette di inviare dati in formato testo al client • void setContentType( String type ) − specifica il tipo MIME della risposta; il tipo MIME aiuta il browser a capire in che modo deve visualizzare i dati (o quale applicazione dovrà eseguire per visualizzare i dati 29 Novembre 2005 Stefano Clemente 16 Gestione delle richieste HTTP get • Una Servlet che gestisce una get deve come prima cosa importare i package javax.servlet e javax.servlet.http • javax.servlet.http fornisce la classe HttpServlet per gestire le richieste HTTP • HttpServlet implementa l’interfaccia javax.servlet.Servlet e aggiunge i metodi per gestire le richieste HTTP • I metodi per la gestione delle richieste HTTP sono per default settati per restituire l’errore di “metodo non permesso” 29 Novembre 2005 Stefano Clemente 17 Gestione delle richieste HTTP get • L’implementazione di una Servlet prevede l’estensione di HttpServlet • per gestire una get bisogna riscrivere il metodo doGet • doGet riceve gli argomenti HttpServletRequest e HttpServletResponse e se − non è in grado di gestire una richiesta client provoca un’eccezione di tipo javax.servlet.ServletException − incontra un errore nella lettura dal client o nella scrittura sullo stesso provoca un’eccezione di tipo javax.servlet.IOException 29 Novembre 2005 Stefano Clemente 18 Gestione delle richieste HTTP get • La Servlet invia la risposta al client − specificando il tipo del contenuto della risposta attraverso il metodo setContentType dell’interfaccia HttpServletResponse − fornendo i contenuti • nel caso di testo attraverso i metodi dell’oggetto PrintWriter, ottenuto come riferimento dall’invocazione del metodo getWriter dell’interfaccia HttpServletResponse • nel caso di dati binari, attraverso i metodi dell’oggetto ServletOutputStream, ottenuto come riferimento dall’invocazione del metodo getOutputStream dell’interfaccia HttpServletResponse • Per scrivere una Servlet si può utilizzare un qualsiasi editor di testo • La Servlet deve essere compilata con javac -d . -classpath <path_classi> nome.java 29 Novembre 2005 Stefano Clemente 19 Esempio 1 • In questo esempio verrà mostrata una Servlet che genera una risposta a una richiesta get di HTTP • La Servlet è richiamata dal documento XHTML WelcomeServlet.html nel quale è definita una form con solo bottone di submit che come azione richiede la Servlet “/advjhtp1/welcome1” con metodo get • La Servlet è la classe WelcomeServlet, che estende HttpServlet e che definisce l’override al metodo doGet − definendo il content type della risposta “text/html” − fornendo tutte le righe del documento XHTML attraverso una serie di invocazioni del metodo println dell’oggetto PrintWriter • println stampa una riga conclusa dal new-line 29 Novembre 2005 Stefano Clemente 20 Esempio 1 <?xml version = "1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <!-- Fig. 9.6: WelcomeServlet.html --> <html xmlns = "http://www.w3.org/1999/xhtml"> <head> <title>Handling an HTTP Get Request</title> </head> <body> <form action = "/advjhtp1/welcome1" method = "get"> <p><label>Click the button to invoke the servlet <input type = "submit" value = "Get HTML Document" /> </label></p> </form> </body> </html> 29 Novembre 2005 Stefano Clemente 21 Esempio 1 // A simple servlet to process get requests. package com.deitel.advjhtp1.servlets; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; public class WelcomeServlet extends HttpServlet { // process "get" requests from clients protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { response.setContentType( "text/html" ); PrintWriter out = response.getWriter(); // send XHTML page to client // start XHTML document out.println( "<?xml version = \"1.0\"?>" ); 29 Novembre 2005 Stefano Clemente 22 Esempio 1 out.println( "<!DOCTYPE html PUBLIC \"-//W3C//DTD " + "XHTML 1.0 Strict//EN\" \"http://www.w3.org" + "/TR/xhtml1/DTD/xhtml1-strict.dtd\">" ); out.println( "<html xmlns = \"http://www.w3.org/1999/xhtml\">" ); // head section of document out.println( "<head>" ); out.println( "<title>A Simple Servlet Example</title>" ); out.println( "</head>" ); // body section of document out.println( "<body>" ); out.println( "<h1>Welcome to Servlets!</h1>" ); out.println( "</body>" ); // end XHTML document out.println( "</html>" ); out.close(); // close stream to complete the page } } 29 Novembre 2005 Stefano Clemente 23 Esempio 1 29 Novembre 2005 Stefano Clemente 24 Apache Tomcat Server • Per eseguire le Servlet occorre un Servlet Container • Tomcat − è un’implementazione degli standard Servlet e JSP − include un server web, ma può essere usato anche per ricevere richieste da altri web server (IIS, Apache) • per questo motivo Tomcat ascolta su una porta diversa dalla 80 (default 8080) in modo da permetterne la convivenza con altri web server sulla stessa macchina − può essere scaricato da http://jakarta.apache.org − come per Apache, esistono versioni per diversi sistemi operativi 29 Novembre 2005 Stefano Clemente 25 Installazione di Tomcat 29 Novembre 2005 Stefano Clemente 26 Installazione di Tomcat 29 Novembre 2005 Stefano Clemente 27 Installazione di Tomcat 29 Novembre 2005 Stefano Clemente 28 Installazione di Tomcat 29 Novembre 2005 Stefano Clemente 29 Tomcat: avvio e arresto 29 Novembre 2005 Stefano Clemente 30 Tomcat: avvio e arresto 29 Novembre 2005 Stefano Clemente 31 Configurazione di un’applicazione web • Le Servlet (come JSP) sono parte dell’applicazione web • Le applicazioni web risiedono per default nella sottodirectory webapps della directory di installazione di Tomcat • Un’applicazione web ha una struttura di directory ben precisa e l’amministratore del sistema su cui Tomcat è installato deve creare questa struttura • La directory dell’applicazione web al livello più alto è detta “context root” 29 Novembre 2005 Stefano Clemente 32 Configurazione di un’applicazione web • Sotto la “context root” vi sono diverse sottodirectory − WEB-INF – contiene il file di descrizione della applicazione web, il file web.xml − WEB_INF/classes – contiene i file class delle Servlet o di supporto alle Servlet; se la classe appartiene a un package, la struttura delle directory del package parte da qui − WEB_INF/lib – contiene i file archivio di Java (JAR) contenenti le classi delle Servlet e altri file di supporto alle servlet • La prima cosa da fare è informare Tomcat della presenza di una nuova applicazione web e della sua context root, modificando il file di configurazione di Tomcat server.xml nella sottodirectory conf della directory di installazione di Tomcat 29 Novembre 2005 Stefano Clemente 33 Configurazione di un’applicazione web <Context path ="/advjhtp1" docBase = "/advjhtp1" reloadable = "true"> </Context> 29 Novembre 2005 Stefano Clemente 34 Configurazione di un’applicazione web • Per gestire le richieste bisogna creare il descrittore dell’applicazione, il file web.xml sotto la directory WEB-INF • In web.xml vengono settati alcuni parametri di configurazione, tra cui − il nome usato per invocare la Servlet − una descrizione della Servlet − la Servlet Mapping, vale a dire il percorso che causa l’invocazione della Servlet 29 Novembre 2005 Stefano Clemente 35 Configurazione di un’applicazione web <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <display-name> TecnInt17 </display-name> <description> TecnInt17 - Esempi </description> <servlet> <servlet-name> welcome1 </servlet-name> 29 Novembre 2005 Stefano Clemente 36 Configurazione di un’applicazione web <description> Esempio di servlet </description> <servlet-class> com.deitel.advjhtp1.servlets.WelcomeServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name> welcome1 </servlet-name> <url-pattern> /welcome1 </url-pattern> </servlet-mapping> </web-app> 29 Novembre 2005 Stefano Clemente 37 29 Novembre 2005 Stefano Clemente 38 29 Novembre 2005 Stefano Clemente 39 Gestione delle richieste HTTP get contenenti dati • Quando si passano dati con il metodo get di HTTP si aggiunge alla URI del documento che si sta richiedendo un “?” e a seguire tutti i parametri nella forma − <nome>=<valore> - nel caso di un solo parametro − <nome_1>=<valore_1>&…&<nome_n>=<valore_n> - nel caso di n parametri • I parametri e i loro valori possono essere recuperati dalla Servlet attraverso il metodo getParameter dell’interfaccia HttpServletRequest • getParameter accetta come argomento il nome di un parametro e restituisce una stringa contenente il valore oppure null se non è stato passato alcun valore con la get 29 Novembre 2005 Stefano Clemente 40 Esempio 2 <?xml version = "1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <!-- Fig. 9.13: WelcomeServlet2.html --> <html xmlns = "http://www.w3.org/1999/xhtml"> <head> <title>Processing get requests with data</title> </head> <body> <form action = "/advjhtp1/welcome2" method = "get"> <p><label> Type your first name and press the Submit button <br /><input type = "text" name = "firstname" /> <input type = "submit" value = "Submit" /> </p></label> </form> </body> </html> 29 Novembre 2005 Stefano Clemente 41 Esempio 2 // Processing HTTP get requests containing data. package com.deitel.advjhtp1.servlets; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; public class WelcomeServlet2 extends HttpServlet { // process "get" request from client protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { String firstName = request.getParameter( "firstname" ); response.setContentType( "text/html" ); PrintWriter out = response.getWriter(); // send XHTML document to client // start XHTML document out.println( "<?xml version = \"1.0\"?>" ); 29 Novembre 2005 Stefano Clemente 42 Esempio 2 out.println( "<!DOCTYPE html PUBLIC \"-//W3C//DTD " + "XHTML 1.0 Strict//EN\" \"http://www.w3.org" + "/TR/xhtml1/DTD/xhtml1-strict.dtd\">" ); out.println( "<html xmlns = \"http://www.w3.org/1999/xhtml\">" ); // head section of document out.println( "<head>" ); out.println( "<title>Processing get requests with data</title>" ); out.println( "</head>" ); // body section of document out.println( "<body>" ); out.println( "<h1>Hello " + firstName + ",<br />" ); out.println( "Welcome to Servlets!</h1>" ); out.println( "</body>" ); // end XHTML document out.println( "</html>" ); out.close(); // close stream to complete the page } } 29 Novembre 2005 Stefano Clemente 43 Esempio 2: modifiche a web.xml ……… <servlet> <servlet-name> welcome2 </servlet-name> <description> Esempio di servlet </description> <servlet-class> com.deitel.advjhtp1.servlets.WelcomeServlet2 </servlet-class> </servlet> ………… <servlet-mapping> <servlet-name> welcome2 </servlet-name> <url-pattern> /welcome2 </url-pattern> </servlet-mapping> ………… 29 Novembre 2005 Stefano Clemente 44 Esempio 2 29 Novembre 2005 Stefano Clemente 45 Gestione delle richieste HTTP post • Poiché i metodi per la gestione delle richieste HTTP sono per default settati per restituire l’errore di “metodo non permesso”, affinché una Servlet possa gestire una richiesta post occorre riscrivere il metodo doPost • La doPost non è diversa dalla doGet che gestisce richieste get contenenti dati • L’accesso ai parametri ricevuti con la post avviene sempre attraverso il metodo getParameter dell’interfaccia HttpServletRequest 29 Novembre 2005 Stefano Clemente 46 Esempio 3 <?xml version = "1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <!-- Fig. 9.16: WelcomeServlet3.html --> <html xmlns = "http://www.w3.org/1999/xhtml"> <head> <title>Handling an HTTP Post Request with Data</title> </head> <body> <form action = "/advjhtp1/welcome3" method = "post"> <p><label> Type your first name and press the Submit button <br /><input type = "text" name = "firstname" /> <input type = "submit" value = "Submit" /> </label></p> </form> </body> </html> 29 Novembre 2005 Stefano Clemente 47 Esempio 3 // Processing post requests containing data. package com.deitel.advjhtp1.servlets; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; public class WelcomeServlet3 extends HttpServlet { // process "post" request from client protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { String firstName = request.getParameter( "firstname" ); response.setContentType( "text/html" ); PrintWriter out = response.getWriter(); // send XHTML page to client // start XHTML document out.println( "<?xml version = \"1.0\"?>" ); 29 Novembre 2005 Stefano Clemente 48 Esempio 3 out.println( "<!DOCTYPE html PUBLIC \"-//W3C//DTD " + "XHTML 1.0 Strict//EN\" \"http://www.w3.org" + "/TR/xhtml1/DTD/xhtml1-strict.dtd\">" ); out.println( "<html xmlns = \"http://www.w3.org/1999/xhtml\">" ); // head section of document out.println( "<head>" ); out.println( "<title>Processing post requests with data</title>" ); out.println( "</head>" ); // body section of document out.println( "<body>" ); out.println( "<h1>Hello " + firstName + ",<br />" ); out.println( "Welcome to Servlets!</h1>" ); out.println( "</body>" ); // end XHTML document out.println( "</html>" ); out.close(); // close stream to complete the page } } 29 Novembre 2005 Stefano Clemente 49 Esempio 3: modifiche a web.xml ……… <servlet> <servlet-name> welcome3 </servlet-name> <description> Esempio di servlet </description> <servlet-class> com.deitel.advjhtp1.servlets.WelcomeServlet3 </servlet-class> </servlet> ………… <servlet-mapping> <servlet-name> welcome3 </servlet-name> <url-pattern> /welcome3 </url-pattern> </servlet-mapping> ………… 29 Novembre 2005 Stefano Clemente 50 Esempio 3 29 Novembre 2005 Stefano Clemente 51 Esempio 4 <?xml version = "1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <!-- Fig. 9.19: RedirectServlet.html --> <html xmlns = "http://www.w3.org/1999/xhtml"> <head> <title>Redirecting a Request to Another Site</title> </head> <body> <p>Click a link to be redirected to the appropriate page</p> <p> <a href = "/advjhtp1/redirect?page=deitel"> www.deitel.com</a><br /> <a href = "/advjhtp1/redirect?page=welcome1"> Welcome servlet</a> </p> </body> </html> 29 Novembre 2005 Stefano Clemente 52 Esempio 4 // Redirecting a user to a different Web page. package com.deitel.advjhtp1.servlets; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; public class RedirectServlet extends HttpServlet { // process "get" request from client protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { String location = request.getParameter( "page" ); if ( location != null ) if ( location.equals( "deitel" ) ) response.sendRedirect( "http://www.deitel.com" ); else if ( location.equals( "welcome1" ) ) response.sendRedirect( "welcome1" ); // code that executes only if this servlet // does not redirect the user to another page response.setContentType( "text/html" ); PrintWriter out = response.getWriter(); 29 Novembre 2005 Stefano Clemente 53 Esempio 4 // start XHTML document out.println( "<?xml version = \"1.0\"?>" ); out.println( "<!DOCTYPE html PUBLIC \"-//W3C//DTD " + "XHTML 1.0 Strict//EN\" \"http://www.w3.org" + "/TR/xhtml1/DTD/xhtml1-strict.dtd\">" ); out.println( "<html xmlns = \"http://www.w3.org/1999/xhtml\">" ); // head section of document out.println( "<head>" ); out.println( "<title>Invalid page</title>" ); out.println( "</head>" ); // body section of document out.println( "<body>" ); out.println( "<h1>Invalid page requested</h1>" ); out.println( "<p><a href = " + "\"servlets/RedirectServlet.html\">" ); out.println( "Click here to choose again</a></p>" ); out.println( "</body>" ); // end XHTML document out.println( "</html>" ); out.close(); // close stream to complete the page } } 29 Novembre 2005 Stefano Clemente 54 Esempio 4: modifiche a web.xml ……… <servlet> <servlet-name> redirect </servlet-name> <description> Esempio di servlet </description> <servlet-class> com.deitel.advjhtp1.servlets.RedirectServlet </servlet-class> </servlet> ………… <servlet-mapping> <servlet-name> redirect </servlet-name> <url-pattern> /redirect </url-pattern> </servlet-mapping> ………… 29 Novembre 2005 Stefano Clemente 55 Esempio 4 29 Novembre 2005 Stefano Clemente 56 Cookie • Il package javax.servlet.http dispone del tipo Cookie per creare e manipolare oggetti cookie Cookie cookie = new Cookie( <lista_informazioni> ) • Quando il cookie va spedito al client, occorre che venga aggiunto alla risposta prima di invocare il metodo getWriter dell’interfaccia HttpServletResponse • La scadenza del cookie è per default legata alla sessione • Si può settare una scadenza diversa invocando il metodo setMaxAge dell’oggetto Cookie e passando come argomento il numero di secondi per il quale il cookie sarà valido 29 Novembre 2005 Stefano Clemente 57 Cookie • Per aggiungere il cookie alla risposta occorre invocare il metodo addCookie dell’interfaccia HttpServletResponse, passando come argomento l’oggetto cookie • Per recuperare il cookie dalla richiesta del client occorre invocare il metodo getCookies dell’interfaccia HttpServletRequest, il quale restituisce − null se non ci sono cookie − un array di oggetti cookie per il quale per ogni elemento si potrà leggere • il nome del cookie attraverso il metodo getName • il valore del cookie attraverso il metodo getValue 29 Novembre 2005 Stefano Clemente 58 Cookie Metodo getComment() Descrizione restituisce una stringa che descrive lo scopo del cookie o null se non esiste un commento getDomain() restituisce una stringa contenente il dominio dei server che possono ricevere il cookie getMaxAge() restituisce un intero che indica la scadenza del cookie (sec) getName() stringa indicante il nome del cookie getPath() stringa che indica la URL del cookie getSecure() boolean che indica se il cookie deve essere trasmesso con protocollo criptato getValue() Stringa contenente il valore del cookie getVersion() Intero che indica la versione del protocollo cookie usato per creare il cookie 29 Novembre 2005 Stefano Clemente 59 Cookie Metodo Descrizione setComment( String ) Setta lo scopo del cookie setDomain( String ) Definisce il dominio dei server che possono ricevere il cookie dal client setMaxAge( int ) Setta la scadenza del cookie in secondi setPath( String ) Indica la URL del server relativa i servizi che possono utilizzare il cookie setSecure( boolean ) Booleano che indica se è necessario il protocollo criptato setValue( String ) Definisce il valore di un cookie setVersion( int ) 29 Novembre 2005 Protocollo del cookie Stefano Clemente 60 Esempio 5 <?xml version = "1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <!-- Fig. 9.22: CookieSelectLanguage.html --> <html xmlns = "http://www.w3.org/1999/xhtml"> <head> <title>Using Cookies</title> </head> <body> <form action = "/advjhtp1/cookies" method = "post"> <p>Select a programming language:</p> <p> <input type = "radio" name = "language" value = "C" />C <br /> <input type = "radio" name = "language" value = "C++" />C++ <br /> <!-- this radio button checked by default --> <input type = "radio" name = "language" value = "Java" checked = "checked" />Java<br /> <input type = "radio" name = "language" value = "VB6" />VB 6 </p> <p><input type = "submit" value = "Submit" /></p> </form> </body> </html> 29 Novembre 2005 Stefano Clemente 61 Esempio 5 // Using cookies to store data on the client computer. package com.deitel.advjhtp1.servlets; import import import import javax.servlet.*; javax.servlet.http.*; java.io.*; java.util.*; public class CookieServlet extends HttpServlet { private final Map books = new HashMap(); // initialize Map books public void init() { books.put( "C", "0130895725" ); 29 Novembre 2005 Stefano Clemente 62 Esempio 5 books.put( "C++", "0130895717" ); books.put( "Java", "0130125075" ); books.put( "VB6", "0134569555" ); } // receive language selection and send cookie containing // recommended book to the client protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { String language = request.getParameter( "language" ); String isbn = books.get( language ).toString(); Cookie cookie = new Cookie( language, isbn ); cookie.setMaxAge( 1000 ); 29 Novembre 2005 Stefano Clemente 63 Esempio 5 response.addCookie( cookie ); // must precede getWriter response.setContentType( "text/html" ); PrintWriter out = response.getWriter(); // send XHTML page to client // start XHTML document out.println( "<?xml version = \"1.0\"?>" ); out.println( "<!DOCTYPE html PUBLIC \"-//W3C//DTD " + "XHTML 1.0 Strict//EN\" \"http://www.w3.org" + "/TR/xhtml1/DTD/xhtml1-strict.dtd\">" ); out.println( "<html xmlns = \"http://www.w3.org/1999/xhtml\">" ); 29 Novembre 2005 Stefano Clemente 64 Esempio 5 // head section of document out.println( "<head>" ); out.println( "<title>Welcome to Cookies</title>" ); out.println( "</head>" ); // body section of document out.println( "<body>" ); out.println( "<p>Welcome to Cookies! You selected " + language + "</p>" ); out.println( "<p><a href = " + "\"/advjhtp1/servlets/CookieSelectLanguage.html\">" + "Click here to choose another language</a></p>" ); out.println( "<p><a href = \"/advjhtp1/cookies\">" + "Click here to get book recommendations</a></p>" ); 29 Novembre 2005 Stefano Clemente 65 Esempio 5 out.println( "</body>" ); // end XHTML document out.println( "</html>" ); out.close(); // close stream } // read cookies from client and create XHTML document // containing recommended books protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { Cookie cookies[] = request.getCookies(); // get cookies 29 Novembre 2005 Stefano Clemente 66 Esempio 5 response.setContentType( "text/html" ); PrintWriter out = response.getWriter(); // start XHTML document out.println( "<?xml version = \"1.0\"?>" ); out.println( "<!DOCTYPE html PUBLIC \"-//W3C//DTD " + "XHTML 1.0 Strict//EN\" \"http://www.w3.org" + "/TR/xhtml1/DTD/xhtml1-strict.dtd\">" ); out.println( "<html xmlns = \"http://www.w3.org/1999/xhtml\">" ); // head section of document out.println( "<head>" ); 29 Novembre 2005 Stefano Clemente 67 Esempio 5 out.println( "<title>Recommendations</title>" ); out.println( "</head>" ); // body section of document out.println( "<body>" ); //if there are any cookies, recommend a book for each ISBN if ( cookies != null && cookies.length != 0 ) { out.println( "<h1>Recommendations</h1>" ); out.println( "<p>" ); // get the name of each cookie for ( int i = 0; i < cookies.length; i++ ) out.println( cookies[ i ].getName() + " How to Program. ISBN#: " + 29 Novembre 2005 Stefano Clemente 68 Esempio 5 cookies[ i ].getValue() + "<br />" ); out.println( "</p>" ); } else { // there were no cookies out.println( "<h1>No Recommendations</h1>" ); out.println( "<p>You did not select a language.</p>" ); } out.println( "</body>" ); // end XHTML document out.println( "</html>" ); out.close(); // close stream } } 29 Novembre 2005 Stefano Clemente 69 Esempio 5: modifiche a web.xml …………… <servlet> <servlet-name> cookies </servlet-name> <description> Esempio di servlet </description> <servlet-class> com.deitel.advjhtp1.servlets.CookieServlet </servlet-class> </servlet> …………… <servlet-mapping> <servlet-name> cookies </servlet-name> <url-pattern> /cookies </url-pattern> </servlet-mapping> ……………… 29 Novembre 2005 Stefano Clemente 70 Esempio 5 29 Novembre 2005 Stefano Clemente 71 Session Tracking: HttpSession • Il supporto per il session tracking è fornito dall’interfaccia HttpSession • Un oggetto HttpSession viene creato invocando il metodo getSession dell’interfaccia HttpServletRequest HttpSession session = request.getSession( true ) • HttpSession dispone di diversi metodi per settare o leggere le informazioni sulla sessione 29 Novembre 2005 Stefano Clemente 72 Session Tracking: HttpSession Metodo getAttribute( String ) getAttributeNames() getCreationTime() getId() getLastAccessedTime() getMaxInactiveInterval() 29 Novembre 2005 Descrizione Restituisce l’oggetto legato al nome fornito come argomento o null se non esiste Restituisce un Enumeration contenente i nomi (stringhe) degli attributi Restituisce l’ora in cui è stata creata la sessione(secondi trascorsi dal 1.1.1970) Restituisce una stringa contenente l’identificatore univoco assegnato alla sessione Restituisce l’ora dell’ultima richiesta formulata dal client in questa sessione (secondi trascorsi dal 1.1.1970) Restituisce il tempo massimo che in questa sessione è trascorso tra due richieste successive Stefano Clemente 73 Session Tracking: HttpSession Metodo Descrizione Restituisce il contesto della servlet getServletContext() al quale la sessione appartiene Invalida la sessione e rilascia tutti invalidate() gli oggetti che le appartengono Restituisce true se il client non è ancora a conoscenza della sessione isNew() o se sceglie di non avviare la sessione Rimuove l’oggetto con il nome removeAttribute( String ) passato come argomento setAttribute( String, value ) Lega un oggetto alla sessione con il nome e il valore specificati setMaxInactiveInterval( int ) Setta la scadenza della sessione in secondi 29 Novembre 2005 Stefano Clemente 74 Esempio 6 <?xml version = "1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <!-- Fig. 9.26: SessionSelectLanguage.html --> <html xmlns = "http://www.w3.org/1999/xhtml"> <head> <title>Using Sessions</title> </head> <body> <form action = "/advjhtp1/sessions" method = "post"> <p>Select a programming language:</p> <p> <input type = "radio" name = "language" value = "C" />C <br /> <input type = "radio" name = "language" value = "C++" />C++ <br /> <!-- this radio button checked by default --> <input type = "radio" name = "language" value = "Java" checked = "checked" />Java<br /> <input type = "radio" name = "language" value = "VB6" />VB 6 </p> <p><input type = "submit" value = "Submit" /></p> </form> </body> </html> 29 Novembre 2005 Stefano Clemente 75 Esempio 6 // Using HttpSession to maintain client state information. package com.deitel.advjhtp1.servlets; import import import import javax.servlet.*; javax.servlet.http.*; java.io.*; java.util.*; public class SessionServlet extends HttpServlet { private final Map books = new HashMap(); // initialize Map books public void init() { books.put( "C", "0130895725" ); books.put( "C++", "0130895717" ); books.put( "Java", "0130125075" ); books.put( "VB6", "0134569555" ); } 29 Novembre 2005 Stefano Clemente 76 Esempio 6 // receive language selection and create HttpSession object // containing recommended book for the client protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { String language = request.getParameter( "language" ); // Get the user's session object. // Create a session (true) if one does not exist. HttpSession session = request.getSession( true ); // add a value for user's choice to session session.setAttribute( language, books.get( language ) ); response.setContentType( "text/html" ); PrintWriter out = response.getWriter(); 29 Novembre 2005 Stefano Clemente 77 Esempio 6 // send XHTML page to client // start XHTML document out.println( "<?xml version = \"1.0\"?>" ); out.println( "<!DOCTYPE html PUBLIC \"-//W3C//DTD " + "XHTML 1.0 Strict//EN\" \"http://www.w3.org" + "/TR/xhtml1/DTD/xhtml1-strict.dtd\">" ); out.println( "<html xmlns = \"http://www.w3.org/1999/xhtml\">" ); // head section of document out.println( "<head>" ); out.println( "<title>Welcome to Sessions</title>" ); out.println( "</head>" ); // body section of document out.println( "<body>" ); out.println( "<p>Welcome to Sessions! You selected " + language + ".</p>" ); 29 Novembre 2005 Stefano Clemente 78 Esempio 6 // display information about the session out.println( "<p>Your unique session ID is: " + session.getId() + "<br />" ); out.println( "This " + ( session.isNew() ? "is" : "is not" ) + " a new session<br />" ); out.println( "The session was created at: " + new Date( session.getCreationTime() ) + "<br />" ); out.println( "You last accessed the session at: " + new Date( session.getLastAccessedTime() ) + "<br />" ); out.println( "The maximum inactive interval is: " + session.getMaxInactiveInterval() + " seconds</p>" ); out.println( "<p><a href = " + "\"servlets/SessionSelectLanguage.html\">" + "Click here to choose another language</a></p>" ); 29 Novembre 2005 Stefano Clemente 79 Esempio 6 out.println( "<p><a href = \"sessions\">" + "Click here to get book recommendations</a></p>" ); out.println( "</body>" ); // end XHTML document out.println( "</html>" ); out.close(); // close stream } // read session attributes and create XHTML document // containing recommended books protected void doGet( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { // Get the user's session object. // Do not create a session (false) if one does not exist. HttpSession session = request.getSession( false ); 29 Novembre 2005 Stefano Clemente 80 Esempio 6 // get names of session object's values Enumeration valueNames; if ( session != null ) valueNames = session.getAttributeNames(); else valueNames = null; PrintWriter out = response.getWriter(); response.setContentType( "text/html" ); // start XHTML document out.println( "<?xml version = \"1.0\"?>" ); out.println( "<!DOCTYPE html PUBLIC \"-//W3C//DTD " + "XHTML 1.0 Strict//EN\" \"http://www.w3.org" + "/TR/xhtml1/DTD/xhtml1-strict.dtd\">" ); out.println( "<html xmlns = \"http://www.w3.org/1999/xhtml\">" ); 29 Novembre 2005 Stefano Clemente 81 Esempio 6 // head section of document out.println( "<head>" ); out.println( "<title>Recommendations</title>" ); out.println( "</head>" ); // body section of document out.println( "<body>" ); if ( valueNames != null && valueNames.hasMoreElements() ) { out.println( "<h1>Recommendations</h1>" ); out.println( "<p>" ); String name, value; // get value for each name in valueNames while ( valueNames.hasMoreElements() ) { name = valueNames.nextElement().toString(); 29 Novembre 2005 Stefano Clemente 82 Esempio 6 value = session.getAttribute( name ).toString(); out.println( name + " How to Program. " + "ISBN#: " + value + "<br />" ); } out.println( "</p>" ); } else { out.println( "<h1>No Recommendations</h1>" ); out.println( "<p>You did not select a language.</p>" ); } out.println( "</body>" ); // end XHTML document out.println( "</html>" ); out.close(); // close stream } } 29 Novembre 2005 Stefano Clemente 83 Esempio 6: web.xml ………… <servlet> <servlet-name> sessions </servlet-name> <description> Esempio di servlet </description> <servlet-class> com.deitel.advjhtp1.servlets.SessionServlet </servlet-class> </servlet> ………… <servlet-mapping> <servlet-name> sessions </servlet-name> <url-pattern> /sessions </url-pattern> </servlet-mapping> ………… 29 Novembre 2005 Stefano Clemente 84 Esempio 6 29 Novembre 2005 Stefano Clemente 85 Accesso ai database • Architettura a n-livelli − Client • Browser − XHTML − HTML − Applet − Application Server • Componenti logiche − Servlets − JSPs • Fornisce l’interfaccia tra il client e il database − DB Server • Acceduto dalle Servlet attraverso JDBC (Java Database Connectivity) 29 Novembre 2005 Stefano Clemente 86 Accesso ai database • Java Database Connectivity (JDBC) − Fornisce un metodo per accedere in modo uniforme ai vari DB (anche DataSource ODBC) • Il livello “application” lavora con qualsiasi database JDBC • I programmatori non devono produrre codice ad-hoc per i vari database • Funziona con query SQL • Le interazioni con il database sono gestite dai driver JDBC − di solito questi driver sono forniti dal produttore del DB − Per TOMCAT esiste già un insieme predefinito di driver (DBCP) contenuto nella libreria commons-dbcp-1.2.1.jar scaricabile dal sito Jakarta e da installare in <directory_Tomcat>\common\lib 29 Novembre 2005 Stefano Clemente 87 Esempio 7 29 Novembre 2005 Stefano Clemente 88 Esempio 7: Survey.html <?xml version = "1.0"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <!-- Survey.html --> <html xmlns = "http://www.w3.org/1999/xhtml"> <head> <title>Survey</title> </head> <body> <form method = "post" action = "/advjhtp1/animalsurvey"> <p>What is your favorite pet?</p> <p> 29 Novembre 2005 Stefano Clemente 89 Esempio 7: Survey.html <input type = "radio" name = "animal" value = "1" />Dog<br /> <input type = "radio" name = "animal" value = "2" />Cat<br /> <input type = "radio" name = "animal" value = "3" />Bird<br /> <input type = "radio" name = "animal" value = "4" />Snake<br /> <input type = "radio" name = "animal" value = "5" checked = "checked" />None </p> <p><input type = "submit" value = "Submit" /></p> </form> </body> </html> 29 Novembre 2005 Stefano Clemente 90 Esempio 7: SurveyServlet.java // A Web-based survey that uses JDBC from a servlet. package com.deitel.advjhtp1.servlets; import import import import import java.io.*; java.text.*; java.sql.*; javax.servlet.*; javax.servlet.http.*; public class SurveyServlet extends HttpServlet { private Connection connection; private PreparedStatement updateVotes, totalVotes, results; // set up database connection and prepare SQL statements public void init( ServletConfig config ) throws ServletException { // attempt database connection and create PreparedStatements try { 29 Novembre 2005 Stefano Clemente 91 Esempio 7: SurveyServlet.java Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); String filename = "c:/web/advjhtp1/pet.mdb"; String database = "jdbc:odbc:Driver={Microsoft Access Driver" + " (*.mdb)};DBQ="; database += filename.trim() + ";DriverID=22;READONLY=true}"; connection = DriverManager.getConnection( database ,"",""); // PreparedStatement to add one to vote total for a // specific animal updateVotes = connection.prepareStatement( "UPDATE surveyresults SET votes = votes + 1 " + "WHERE id = ?" ); // PreparedStatement to sum the votes totalVotes = connection.prepareStatement( "SELECT sum( votes ) FROM surveyresults" ); 29 Novembre 2005 Stefano Clemente 92 Esempio 7: SurveyServlet.java data } ); } // PreparedStatement to obtain surveyoption table's results = connection.prepareStatement( "SELECT surveyoption, votes, id " + "FROM surveyresults ORDER BY id" ); // for any exception throw an UnavailableException to // indicate that the servlet is not currently available catch ( Exception exception ) { exception.printStackTrace(); throw new UnavailableException( exception.getMessage() } // end of init method // process survey response 29 Novembre 2005 Stefano Clemente 93 Esempio 7: SurveyServlet.java protected void doPost( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { // set up response to client response.setContentType( "text/html" ); PrintWriter out = response.getWriter(); DecimalFormat twoDigits = new DecimalFormat( "0.00" ); // start XHTML document out.println( "<?xml version = \"1.0\"?>" ); out.println( "<!DOCTYPE html PUBLIC \"-//W3C//DTD " + "XHTML 1.0 Strict//EN\" \"http://www.w3.org" + "/TR/xhtml1/DTD/xhtml1-strict.dtd\">" ); out.println( "<html xmlns = \"http://www.w3.org/1999/xhtml\">" ); // head section of document 29 Novembre 2005 Stefano Clemente 94 Esempio 7: SurveyServlet.java out.println( "<head>" ); // read current survey response int value = Integer.parseInt( request.getParameter( "animal" ) ); // attempt to process a vote and display current results try { // update total for current survey response updateVotes.setInt( 1, value ); updateVotes.executeUpdate(); // get total of all survey responses ResultSet totalRS = totalVotes.executeQuery(); totalRS.next(); int total = totalRS.getInt( 1 ); // get results 29 Novembre 2005 Stefano Clemente 95 Esempio 7: SurveyServlet.java ResultSet resultsRS = results.executeQuery(); out.println( "<title>Thank you!</title>" ); out.println( "</head>" ); out.println( "<body>" ); out.println( "<p>Thank you for participating." ); out.println( "<br />Results:</p><pre>" ); // process results int votes; while ( resultsRS.next() ) { out.print( resultsRS.getString( 1 ) ); out.print( ": " ); votes = resultsRS.getInt( 2 ); out.print( twoDigits.format( ( double ) votes / total * 100 ) ); out.print( "% responses: " ); out.println( votes ); } 29 Novembre 2005 Stefano Clemente 96 Esempio 7: SurveyServlet.java resultsRS.close(); out.print( "Total responses: " ); out.print( total ); } // end XHTML document out.println( "</pre></body></html>" ); out.close(); // if database exception occurs, return error page catch ( SQLException sqlException ) { sqlException.printStackTrace(); out.println( "<title>Error</title>" ); out.println( "</head>" ); out.println( "<body><p>Database error occurred. " ); out.println( "Try again later.</p></body></html>" ); out.close(); } 29 Novembre 2005 Stefano Clemente 97 Esempio 7: SurveyServlet.java } // end of doPost method // close SQL statements and database when servlet terminates public void destroy() { // attempt to close statements and database connection try { updateVotes.close(); totalVotes.close(); results.close(); connection.close(); } } } // handle database exceptions by returning error to client catch( SQLException sqlException ) { sqlException.printStackTrace(); } // end of destroy method 29 Novembre 2005 Stefano Clemente 98 Esempio 7: web.xml ………… <servlet> <servlet-name> animalsurvey </servlet-name> <description> Esempio di servlet </description> <servlet-class> com.deitel.advjhtp1.servlets.SurveyServlet </servlet-class> </servlet> ………… <servlet-mapping> <servlet-name> animalsurvey </servlet-name> <url-pattern> /animalsurvey </url-pattern> </servlet-mapping> ………… 29 Novembre 2005 Stefano Clemente 99