Tecnologie lato Server: Servlet Stefano Clemente s.clemente@ei.unibo.it © 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/onlineTraining/Servlets/Fundamentals/ http://jakarta.apache.org 29 Novembre 2005 Stefano Clemente
Introduzione Java permette lo sviluppo di applicazioni Java permette 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
Introduzione Servlet JSP 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 javax.servlet.jsp javax.servlet.tagext che estendono le funzionalità delle servlet alle JSP 29 Novembre 2005 Stefano Clemente
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
Esempio 1 29 Novembre 2005 Stefano Clemente
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
Installazione di Tomcat 29 Novembre 2005 Stefano Clemente
Installazione di Tomcat 29 Novembre 2005 Stefano Clemente
Installazione di Tomcat 29 Novembre 2005 Stefano Clemente
Installazione di Tomcat 29 Novembre 2005 Stefano Clemente
Tomcat: avvio e arresto 29 Novembre 2005 Stefano Clemente
Tomcat: avvio e arresto 29 Novembre 2005 Stefano Clemente
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
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
Configurazione di un’applicazione web <Context path ="/advjhtp1" docBase = "/advjhtp1" reloadable = "true"> </Context> 29 Novembre 2005 Stefano Clemente
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
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
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
29 Novembre 2005 Stefano Clemente
29 Novembre 2005 Stefano Clemente
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
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
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
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>" ); "<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
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> <url-pattern> /welcome2 </url-pattern> </servlet-mapping> 29 Novembre 2005 Stefano Clemente
Esempio 2 29 Novembre 2005 Stefano Clemente
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
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
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
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>" ); "<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
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> <url-pattern> /welcome3 </url-pattern> </servlet-mapping> 29 Novembre 2005 Stefano Clemente
Esempio 3 29 Novembre 2005 Stefano Clemente
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
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
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
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> <url-pattern> /redirect </url-pattern> </servlet-mapping> 29 Novembre 2005 Stefano Clemente
Esempio 4 29 Novembre 2005 Stefano Clemente
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
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
Cookie Metodo Descrizione getComment() 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
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 ) Protocollo del cookie 29 Novembre 2005 Stefano Clemente
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 /> value = "C++" />C++ <br /> <!-- this radio button checked by default --> value = "Java" checked = "checked" />Java<br /> value = "VB6" />VB 6 </p> <p><input type = "submit" value = "Submit" /></p> </form> </body> </html> 29 Novembre 2005 Stefano Clemente
Esempio 5 // Using cookies to store data on the client computer. package com.deitel.advjhtp1.servlets; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import 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
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
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
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
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
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
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
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
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> <url-pattern> /cookies </url-pattern> </servlet-mapping> ……………… 29 Novembre 2005 Stefano Clemente
Esempio 5 29 Novembre 2005 Stefano Clemente
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
Session Tracking: HttpSession Metodo Descrizione getAttribute( String ) Restituisce l’oggetto legato al nome fornito come argomento o null se non esiste getAttributeNames() Restituisce un Enumeration contenente i nomi (stringhe) degli attributi getCreationTime() Restituisce l’ora in cui è stata creata la sessione(secondi trascorsi dal 1.1.1970) getId() Restituisce una stringa contenente l’identificatore univoco assegnato alla sessione getLastAccessedTime() Restituisce l’ora dell’ultima richiesta formulata dal client in questa sessione (secondi trascorsi dal 1.1.1970) getMaxInactiveInterval() Restituisce il tempo massimo che in questa sessione è trascorso tra due richieste successive 29 Novembre 2005 Stefano Clemente
Session Tracking: HttpSession Metodo Descrizione getServletContext() Restituisce il contesto della servlet al quale la sessione appartiene invalidate() Invalida la sessione e rilascia tutti gli oggetti che le appartengono isNew() Restituisce true se il client non è ancora a conoscenza della sessione o se sceglie di non avviare la sessione removeAttribute( String ) Rimuove l’oggetto con il nome 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
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 /> value = "C++" />C++ <br /> <!-- this radio button checked by default --> value = "Java" checked = "checked" />Java<br /> value = "VB6" />VB 6 </p> <p><input type = "submit" value = "Submit" /></p> </form> </body> </html> 29 Novembre 2005 Stefano Clemente
Esempio 6 // Using HttpSession to maintain client state information. package com.deitel.advjhtp1.servlets; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import 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
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
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
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
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
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
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
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
Esempio 6: web.xml ………… <servlet> <servlet-name> sessions <description> Esempio di servlet </description> <servlet-class> com.deitel.advjhtp1.servlets.SessionServlet </servlet-class> </servlet> <servlet-mapping> <url-pattern> /sessions </url-pattern> </servlet-mapping> 29 Novembre 2005 Stefano Clemente
Esempio 6 29 Novembre 2005 Stefano Clemente
Accesso ai database Architettura a n-livelli Client Application Server 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
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
Esempio 7 29 Novembre 2005 Stefano Clemente
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
Esempio 7: Survey.html <input type = "radio" name = "animal" value = "1" />Dog<br /> value = "2" />Cat<br /> value = "3" />Bird<br /> value = "4" />Snake<br /> value = "5" checked = "checked" />None </p> <p><input type = "submit" value = "Submit" /></p> </form> </body> </html> 29 Novembre 2005 Stefano Clemente
Esempio 7: SurveyServlet.java // A Web-based survey that uses JDBC from a servlet. package com.deitel.advjhtp1.servlets; import java.io.*; import java.text.*; import java.sql.*; import javax.servlet.*; import 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
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
Esempio 7: SurveyServlet.java // PreparedStatement to obtain surveyoption table's data 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
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
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
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
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>" ); 29 Novembre 2005 Stefano Clemente
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
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> <url-pattern> /animalsurvey </url-pattern> </servlet-mapping> 29 Novembre 2005 Stefano Clemente