1 Corso di Ingegneria del Web e Applicazioni A A Domenico Rosaci 20 – Web Applications – Servlet e JSP
2 Servlet e JSP Introduzione alle servlet nServlet: oggetti java caricati ed eseguiti dal web server all’interno del processo di richiesta/risposta di servizi. nConsentono l’estensione delle potenzialità dei servizi di rete nweb server: agisce come un container che gestisce il ciclo di vita delle servlet nIl web server: passa alle servlet i dati del client e restituisce ai client i dati prodotti dall’esecuzione delle servlet Es. Una servlet può estendere le potenzialità di un web server ricevendo i dati inseriti da un client attraverso una form e operando su di essi inserendoli per esempio in un DB.
3 Servlet e JSP Servlet: caratteristiche nLe servlet non vengono eseguite in processi separati, quindi ogni richiesta non causa la creazione di un nuovo processo nLe servlet risiedono in memoria tra una richiesta e l’altra, quindi vengono caricate solo una volta, alla prima richiesta. Ciò comporta che anche le inizializzazioni necessarie vengono eseguite una volta sola nUna solo istanza della servlet risponde a più richieste nDispongono di classi per la gestione delle sessioni nGarantiscono maggiore velocità di esecuzione rispetto a script CGI nConsentono una più semplice condivisione dei dati fra le istanze di una servlet nEreditano la portabilità di Java
4 Servlet e JSP Architettura nIl package Java di base per le API Servlet è javax.servlet: –contiene la definizione dell’interfaccia Servlet e –contiene classi utili alla comunicazione fra client e server nL’interfaccia Servlet –contiene i prototipi di tutti i metodi necessari alla gestione del ciclo di vita di una servlet e alla esecuzione delle operazione implementate dalla servlet –i metodi definiti in questa interfaccia devono essere supportati da tutte le servlet nTutte le servlet sono classi che implementano l’interfaccia servlet, o in maniera diretta, o estendendo una classe che la implementa come ad esempio HttpServlet
5 Servlet e JSP Architettura nIl package javax.servlet.http fornisce classi che estendono le funzionalità di base di una servlet adottando le caratteristiche del protocollo http come –gestione dei metodi HTTP (GET, POST) –gestione degli header HTTP nPer creare una servlet che utilizzi il protocollo http per ricevere e fornire dati si può implementare una classe che estenda la classe javax.servlet.http.HttpServlet
6 Servlet e JSP Architettura nQuando una servlet accetta una richiesta da un client riceve due oggetti: –ServletRequest, utilizzato per la comunicazioner dal client verso il server –ServletResponse, utilizzato per gestire la comunicazioie dal server verso il client Estensioni di queste classi consentono di disporre di metodi per manipolare informazioni e header specifici di determinati protocolli. In particolare le servlet che utilizzano il protocollo HTTP usano oggetti che sono istanza delle classi HttpServletRequest e HttpServletResponse
7 Servlet e JSP Servlet concorrenti nIl web server per definizione utilizza una sola istanza di servlet condividendola fra le varie richieste nN richieste da parte di client della stessa servlet portano alla creazione di n threads differenti da parte del web server capaci di eseguire la servlet in maniera concorrente. nIn fase di programmazione si deve tenere conto dei meccanismi di accesso concorrente alle servlet a ai loro dati. nL’operatore synchronized consente di sincronizzare blocchi di codice della servlet (o anche tutto il metodo service) difendendoli da accessi concorrenti da parte di più threads. nPer creare più istanze di una stessa servlet da associare alle richieste, la servlet deve implementare l’interfaccia SingleThreadModel. In questo modo il web server creerà più istanza della stessa servlet al momento del caricamento dell’oggetto e assegnerà ai threads solo istanza libere.
8 Servlet e JSP L’oggetto HttpServerRequest Rappresenta una richiesta http e mediante i metodi di questa classe è possibile –accedere a parametri o meta informazioni relative alla richiesta. Es: getRequestURI() restituisce l’URI richiesto getMethod() fornisce il metodo HTTP utilizzato per inoltrare la richiesta il metodo getParameter(String) consente di accedere per nome ai parametri contenuti nella query string –creare gli stream di input e la possibilità quindi di ricevere i dati della richiesta attraverso i metodi getInputStream e getReader
9 Servlet e JSP L’oggetto HttpServerResponse Fornisce alla servlet i metodi per rispondere al client: –permette di fissare parametri relativi alla risposta inviata (come lunghezza o tipo MIME) –fornisce metodi per manipolare gli header del protocollo http –rende possibile il reindirizzamento –fornisce i metodi per creare gli stream di output e la possibilità quindi di inviare i dati della risposta. getOutputStream per l’invio di dati in forma binaria getWriter per l’invio attraverso il canale System.out –definisce una serie di costanti per inviare al browser il risultato della operazione richiesta
10 Servlet e JSP Ciclo di vita delle servlet Il ciclo di vita di una servlet definisce: –come una servlet viene caricata: caricamento e istanziazione sono eseguiti dal web server e avvengono al momento della prima richiesta da parte dei client –come una servlet viene inizializzata: in questa fase la servlet carica dati persistenti, apre connessioni verso DB. Questa operazione avviene tramite la chiamata al metodo init(). Il metodo di default non esegue nessuna operazione –come può ricevere e rispondere alle richieste dei client: il metodo eseguito all’arrivo di una nuova richiesta è il metodo service(), che riceve come parametri gli oggetti ServletRequest e ServletResponse per gestire le richieste –come viene terminata (tipicamente quando termina l’esecuzione del web server): ad esempio si specifica come rilasciare le risorse occupate. Questa operazione avviene tramite la chiamata al metodo destroy()
11 Servlet e JSP Inizializzazione di una servlet nL’inizializzazione di una servlet avviene con la chiamata del metodo init() al momento del suo caricamento nUn solo thread viene eseguito al momento della inizializzazione nLe richieste possono essere ricevute dalla servlet solo dopo il completamento della fase di inizializzazione nSe la servlet non riesce a completare l’inizializzazione viene generata una eccezione nIl metodo init() riceve come parametro un oggetto di tipo ServletConfig che contiene la configurazione iniziale di una servlet. Per salvare la configurazione si puo’ richiamare il metodo super.init, altrimenti si deve implemetare questa operazione nel nuovo init.
12 Servlet e JSP Inizializzazione di una servlet nI parametri di configurazione di una servlet sono definiti all’interno della configurazione del web server che li comunica alla servlet nella forma chiave=valore. nI metodi utilizzati dall’oggetto ServletConfig per accedere ai parametri sono: getInitParameterNames() e getInitParameter(String) nSi puo accedere ai parametri di configurazione anche tramite il metodo getServletConfig() dell’interfaccia servlet all’interno del metodo service() Es. public void init(ServletConfig config){ super.init(config); String initpar = config.getInitParameter(‘PARAMETER’); if(initpar== null){ throw new UnavailableException(this,”errore!”) }}
13 Il metodo service() nSe il metodo service() non viene sovrascritto, la nostra classe eredita il metodo definito all’interno della classe che andiamo ad estendere nSe estendiamo la classe HttpServlet, questo metodo ha la funzione di distribuire la gestione della richiesta fra altri metodi in base al tipo di richiesta ricevuta. Ad esempio in caso di richiesta GET o POST vengono richiamati in automatico rispettivamente i metodi doGet() e doPost() Nel caso non si implementi una nuova versione del metodo service() sarà necessario implementare nella nostra classe un metodo scelto fra questi in base al tipo di richiesta da gestire. Servlet e JSP
14 Servlet e JSP Interazione con client Scrivere una servlet che estende la classa HttpServlet per gestire il protocollo HTTP comporta l’implementazione dei metodi definiti per gestire l’interazione HTTP col client che si ritengono necessari. Es. –doGet, per gestire richiesta di tipo GET o HEAD –doPost, per gestire richiesta di tipo POST –doPut, per gestire richiesta di tipo PUT Di default queste richieste restituiscono il codice HTTP BAD_REQUEST (400) Tali metodi ricevono tutti 2 argomenti, gli oggetti HttpServletRequest e HttpServletResponse per la gestione dei dati ricevuti o inviati al client
15 Servlet e JSP Interazione con client Il modo in cui si accede ai dati del client può dipendere dal metodo HTTP della richiesta: –Con tutti i metodi HTTP, il metodo getParameterValues fornisce i valori in base al nome del parametro, il metodo getParameterNames fornisce i nomi dei parametri –Col metodo GET si può utilizzare il motodo getQueryString che restituisce una stringa da parserizzare –Con i metodi POST,PUT si può scegliere fra i metodi getReader per la lettura di dati di tipo testo o getInputStream per la creazione di uno stream per la lettura di dati binari Per inviare dati al client sono disponibili invece i metodi –getWriter, per inviare dei dati di tipo testo –getOutputStream per inviare dati binari
16 Servlet e JSP Interazione con client Procedura per l’invio di dati ( per esempio nella creazione di una pagina html dinamica): nPrima di inviare dati tramite l’oggetto PrinterWriter o OutputStream, è necessario fissare gli header HTTP. nLa classe HttpServletResponse fornisce dei metodi per accedere e fissare gli header della risposta, come il content- type, encoding, content lenght. nUna volta impostati gli header della risposta, si può inviare il body
17 Servlet e JSP Un esempio: Hello World! Vogliamo creare una servlet la cui chiamata da parte di un client restituisca una semplice pagina HTML con la scritta “Hello World!”: nCreiamo un file HelloWorldServlet.java nCompiliamo il file con javac per ottenere il file HelloWorldServlet.class nRendiamo il file disponibile via web attraverso un URL
18 Servlet e JSP Un esempio: Hello World! nImport dei package necessari alla servlet Import java.io.*; import java.servlet.*; import java.servlet.http.*; nDichiarazione della classe che sarà la nostra servlet. Poiché creiamo una servlet HTTP estendiamo la classe javax.servlet.http.HttpServlet public class CiaoMondoServlet extends HttpServlet nVolendo far gestire alla nostra servlet richieste di tipo GET, ridefiniamo il metodo doGet() protected void doGet(HttpServletRequest req, HttpServletResponse res) nImpostiamo il tipo MIME della risposta da inviare al client. res.setContentType(“text/html”);
19 Servlet e JSP Un esempio: Hello World! nCreiamo un oggetto PrintWriter associato alla risposta per la scrittura verso il client. PrinterWriter out =res.getWriter(); nUtilizziamo l’oggetto PrintWriter per creare il testo della pagina da inviare al client. out.println(“ HelloWorld! ”); nChiudiamo l’oggetto PrintWriter ( il server chiude gli stream di input/output automaticamente alla terminazione dell’esecuzione di una servlet). out.close(); Questa chiamata informa il server che la risposta è terminata e la connessione può essere chiusa
20 Servlet e JSP Un esempio: Hello World! Import java.io.*; import java.servlet.*; import java.servlet.http.*; public class HelloWorldServlet extends Httpservlet{ protected void doGet(HttpServletRequest req, HttpServletResponse) throws ServletException, IOException{ res.setContentType(“text/html”); PrinterWriter out =res.getWriter(); out.println(“ HelloWorld! ”); out.close(); }
21 Servlet e JSP Ottenere informazioni sul client Sovracrivere service() per ottenere informazioni sulla richiesta del client: public class InfoClient extends HttpServlet{ public void service(HttpServletRequest req, HttpServletResponse) throws ServletException, IOException{ res.setContentType(“text/html”); PrinterWriter out =res.getWriter(); out.println(“ Informazioni ”); out.println(req.getProtocol()+” ”); out.println(req.getServerPort()+” ”); out.println(req.getCharacterEncoding()+” ”); out.println(req.getRemoteHost()+” ”); out.println(“ ”); out.println(“ }
22 Servlet e JSP Gestire il metodo POST - 1 Creiamo una servlet che riceve da input due campi inseriti dall’utente e li salva su file. La form di inserimento sarà: Test servlet
23 Servlet e JSP Gestire il metodo POST - 2 Public void doPost (HttpServletRequest req, HttpServletResponse) throws ServletException, IOException{ res.setContentType(“text/html”); PrinterWriter out =res.getWriter(); FileWriter myFile = new FileWriter(“nomefile”,true); PrinterWriter toMyFile = new PrinterWriter(myFile); Enumeration values = req.getParameterNames(); while(values.hasMoreElements()){ String name = (String) valus.nextElement); String value = req.getParameterValues(name); if(name.compareTo(“submit)!=0){ toMyFile.println(name+”:”+value);} } myFile.close(); out.println(“ Scrittura eseguita ”); out.close();}
24 Servlet e JSP Servlet: uso delle query string Utilizzando il metodo GET del protocollo http i dati inviati dal client vengono appesi alla URL richiesta nella forma di coppie nome=valore ES. I valori di una query string possono essere recuperati utilizzando i seguenti metodi della classe HttpServletRequest nString getQueryString() ritorna la query string completa nEnumeration getParameterNames() ritorna una enumerazione dei nomi dei parametri nString getParameter(String) ritorna il valore del parametro a partire dal suo nome nString[] getParameterValues() ritorna una array di valori del parametro
25 Servlet e JSP Uso delle sessioni nUna sessione è rappresentata attraverso la classe HttpSession nLa creazione di una sessione può essere fatta all’interno dei metodi doGet o doPost tramite il metodo getSession dell’oggetto HttpServletRequest HttpSession session = req.getSession(true); nCon questa chiamata la servlet cerca di identificare il client, e se non esiste già una sessione associata alla richiesta ne viene creata una nuova. nUna volta ottenuto l’oggetto session, questo può essere utilizzato tramite i suoi metodi per memorizzare qualsiasi tipo di informazione. nUn sessione rimane valida finchè non viene invalidata col metodo invalidate(), oppure scade il suo timeout.
26 Servlet e JSP Uso delle sessioni nLa creazione di una sessione comporta in pratica la predisposizione di un’area di memoria per la gestione delle informazioni e la creazione “trasparente” di un cookie con un numero di sessione. nSe il browser non supporta il cookie, il numero di sessione viene registrato nelle query string al momento della creazione del codice della pagina. nI metodi dell’oggetto HttpSession permettono di avere informazioni sulla sessione (id della sessione, tempo trascorso, tempo di inattività) o di memorizzare dati di sessione nella forma di coppia nome=valore. putValue(String name,Object value) void removeValue(String name)
27 Servlet e JSP Es. di uso delle Sessioni public void service(HttpServletRequest req, HttpServletResponse) throws ServletException, IOException{ res.setContentType(“text/html”); PrinterWriter out = res.getWriter(); out.println(“…..”); //stampo i tag iniziali HttpSession sessione = req.getSession(true); if(session.isNew()){ out.println(“ Tempo di creazione:”+session.creationTime()); session.putValue(“accessi”,new Integer(1)); }else{ int accessi=((Integer)session.getValue(“accessi”)).intValue(); accessi++; out.println(“ Numero accessi:”+accessi);} out.println(…);//stampo i tag finali out.close }
28 Servlet e JSP Es. di gestione di una lista - 1 Come esempio vediamo l’implementazione di una servlet per la gestione di una mailing list. La struttura della servlet è: public class ListManagerServlet extends HttpServlet{ private Vector list; init();//esegue le inizializzazioni doGet(); //riceve la richiesta della lista della mailing list doPost();//riceve i dati per l’inserimento di un //nuovo indirizzo subscribe()//esegue una nuova sottoscrizione unsubscribe()//cancella un indirizzo save()//salva le modifiche }
29 Servlet e JSP Es.di gestione di una lista - 2 Il metodo doGet è: Protected void doGet (HttpServletRequest req, HttpServletResponse) throws ServletException, IOException{ res.setContentType(“text/html”); res.setHeader(“pragma”,”no-cache”); PrinterWriter out = res.getWriter(); out.print(“ …..”); for(i=0;i< list.size();i++){ out.print(“ ”+ list.elementAt(i); } out.print(“ ”); out.print(“….. ”); out.close; }
30 Servlet e JSP Es. di gestione di una lista - 3 public void doPost (HttpServletRequest req, HttpServletResponse) throws ServletException, IOException{ String =req.getParameter;String msg; if( ==null){ res.sendError(res.SC_BAD_REQUEST,”nessun indirizzo ins.”); return;} if(req.getParameter(“action”).equals(“subscribe”)){ if(subscribe( )) msg=“Sottoscrizione avvenuta”; else{ res.sendError(res.SC_BAD_REQUEST,”nessun indirizzo ins.”); return;} }else{ if(unsubscribe( )) msg=“Rimozione avvenuta”; else{ res.sendError(res.SC_BAD_REQUEST,”errore!”); return;}}
31 Servlet e JSP Es. di gestione di una lista - 4 res.setContentType(“text/html”); res.setHeader(“pragma”,”no-cache”); PrinterWriter out = res.getWriter(); out.print(“ ”); out.print(msg); out.print(”<A HREF=\””); out.print(req.getRequestURI()); out.print(“\”>>Torna alla lista”); out.print(“….. ”); out.close(); }
32 Servlet e JSP Es. di gestione di una lista - 5 I metodi per registrare le operazioni degli utenti sono: private syncronized boolean subscribe(String )throws IOException{ if(! list.contains( )) return false; list.addElement( ); save(); return true; } private syncronized boolean unsubscribe(String )throws IOException{ if(! list.removeElement( )) return false; save(); return true; }
33 Servlet e JSP Uso dei Cookie nL’oggetto Session utilizza i cookie per consentire l’identificazione delle sessioni ma memorizza i parametri della sessione sul server. nI cookie possono essere utilizzati per memorizzare altre informazioni sul client nLa Java fornisce la classe javax.servlet.http.Cookie per rappresentare e gestire i cookie senza dover manipolare gli header http. nSui cookie si può definire: –il dominio applicativo (metodo setDomain) –il path dell’applicazione (metodo setPath) –la durata di validità(metodo setMAxAge) nI cookie possono essere aggiunti o letti attraverso l’oggetto HttpServletRequest
34 Servlet e JSP Uso dei cookie:esempio //Aggiungere un nuovo cookie Cookie mycookie=null; String nome=“nome_cookie”; String valore=“valore_cookie”; mycookie=new Cookie(nome,valore); mycookie.setMaxAge(1000); res.addCookie(); //Leggere i cookie ricevuti Cookie cookies[]=req.getCookies(); for(int i=0;i<cookies.length;i++){ Cookie cookie_ric=cookies[i]; out.print(cookie_ric.getName()+”=“+ cookie_ric.getValue()); }
35 Servlet e JSP Il tag Le servlet possono essere richiamati anche tramite uno speciale tag HTML, Es. Quando una pagina con questi tag viene richiamata, i tag mandano in esecuzione la servlet specificata e vengono poi sostituiti dal risultato della loro elaborazione. I tag specificano dei parametri da passare alle servlet, che comunque possono accedere ai parametri spediti via GET o POST.
36 Servlet e JSP Link utili nhttp://java.sun.com/products/servl et/index.html nhttp://java.apache.org/
37 Cos’è una JSP? Di fatto una pagina JSP è una Servlet Oltre ai vantaggi delle Servlet offre: –Look-and-feel HTML (plain-text) –Facilità per i web designer –Sviluppo senza programmare in Java tramite l’uso di custom tags e expression language (EL) –Compilazione e deployment automatico da parte del Servlet container Si dovrebbe concentrare solo sul livello di “presentazione” (GUI) –La logica applicativa implementata altrove Servlet e JSP
38 Java Servlet vs. JSP (1) Servlet e JSP
39 Java Servlet vs. JSP (2) Servlet e JSP
40 JSP: Ciclo di Vita Simile a quello di una Servlet “classica” Se l’istanza della Servlet corrispondente alla richiesta non esiste, il Servlet container: –Compila la JSP nella Servlet corrispondente –Carica la classe e la istanzia –Inizializza l’istanza della classe Servlet tramite il metodo jspInit Per ogni richiesta utente, il container invoca il metodo _jspService della Servlet associata alla JSP, passando gli oggetti request e response Se rimossa, il container invoca il metodo jspDestroy Servlet e JSP
41 JSP: Compilazione La compilazione da JSP a Servlet avviene in 2 passi: 1.Il file.jsp viene compilato in un file.java dal compilatore del container Jasper su JBoss/Tomcat 2.Il file.java generato dal compilatore viene a sua volta compilato in un file.class dal compilatore Java standard (javac) Ecco perché il Servlet container necessita dell’intero JDK e non della sola piattaforma JRE Servlet e JSP
42 JSP: Note sulla compilazione La conversione.jsp .java .class avviene soltanto una volta o a fronte di una modifica del file.jsp I file generati (.java e.class) su JBoss si trovano in: server/default/work/jboss.web/localhost/ myapplication/org/apache/jsp/MyJSP_js p.java Servlet e JSP
43 MyFirstJSP con Eclipse Creare un nuovo Dynamic Web Project Creare una JSP tramite Eclipse Packaging tramite WAR Deployment Testing Servlet e JSP
44 MyFirstJSP con Eclipse Servlet e JSP
45 MyFirstJSP con Eclipse Servlet e JSP
46 Hello.jsp: Implementazione Servlet e JSP
47 Hello.jsp: Implementazione Servlet e JSP
48 Hello.jsp: Deployment+Testing Servlet e JSP
49 Da JSP a Java Servlet Servlet e JSP
50 JSP API Il contenuto della pagina JSP viene eseguito all’interno del metodo generato _jspService Tutti i contenuti statici sono convertiti in chiamate a out.write() Tutti contenuti dinamici (inclusi nei tag ) vengono eseguiti come codice Java “normale” Servlet e JSP
51 JSP: Oggetti “impliciti” Il metodo generato automaticamente con la compilazione.jsp .java definisce e inizializza alcuni oggetti Questi oggetti possono essere riferiti all’interno della stessa pagina J SP Servlet e JSP
52 JSP: Oggetti “impliciti” Servlet e JSP
53 Sintassi JSP: Direttive Le direttive JSP controllano la compilazione da JSP a Servlet Non hanno alcun effetto sul comportamento a run-time Controllano solo la fase di generazione di codice Servlet e JSP
54 Sintassi JSP: Direttiva Page Servlet e JSP
55 Sintassi JSP: Direttiva Include Include il contenuto di un altro file JSP a tempo di traduzione/compilazione Analogo ad editare in contenuto del file JSP incluso direttamente nel file JSP che lo include Servlet e JSP
56 Sintassi JSP: Direttiva Taglib Fornisce accesso a librerie di tag standard e custom Più avanti esamineremo JSTL Servlet e JSP
57 Sintassi JSP: Scriptlets Rappresentano porzioni di codice Java all’interno di una pagina JSP La sintassi per inserire scriptlets è la seguente: oppure … Una volta tradotta la pagina JSP diventano parte del metodo _jspService Come qualsiasi porzione di codice Java: –tutti gli statement devono terminare con il “;” –tutte le parentesi devono essere bilanciate L’uso massiccio di scriptlet è sconsigliato poiché “snatura” il vero ruolo di una pagina JSP –interfaccia vs. logica applicativa Servlet e JSP
58 Sintassi JSP: Scriptlets (esempio) Servlet e JSP
59 Sintassi JSP: Expressions Simili agli scriptlets ma più specifiche Il risultato di un’espressione è inviato allo stream che gestisce la risposta La sintassi è la seguente: oppure java expr Le espressioni non devono essere terminate con “;” perché vengono convertite in out.print(java expr); Servlet e JSP
60 Sintassi JSP: Expressions (esempi) Servlet e JSP
61 Sintassi JSP: Declarations Usate per dichiarare metodi e variabili al di fuori dello scope del metodo _jspService –sia di istanza che statici La sintassi è la seguente: oppure java decl Consentono il riuso del codice sebbene vi siano alternative migliori –custom tags e beans Servlet e JSP
62 Sintassi JSP: Declarations (esempio) Servlet e JSP
63 Sintassi JSP: Comments Usati per commentare porzioni di pagina JSP Sia contenuti statici Sia contenuti dinamici --%> Non ci possono essere commenti annidati NOTA: I commenti Java tradizionali si possono usare all’interno degli scriptlets, espressioni (tranne “//”) e le dichiarazioni Servlet e JSP