530 likes | 654 Views
Accessi paralleli (one-shot) a servizio. SERVLET ….. if (operazione.equals(“attori”) { cerca nomi attori in DB } else if ( operazione.equals(“titoli”) { cerca titoli film in DB } else { genera saluto ad account } ….. stampa pagina di output su PrintWriter chiudi PrintWriter. Web
E N D
Accessi paralleli (one-shot) a servizio SERVLET ….. if (operazione.equals(“attori”) { cerca nomi attori in DB} else if (operazione.equals(“titoli”) { cerca titoli film in DB} else {genera saluto ad account } ….. stampa pagina di output su PrintWriter chiudi PrintWriter Web server Applicazione Web browser2 browser1 Laboratorio di Servizi Web - servlet2 - Ardissono
Gestione interazione con utente • Esempi di Servlet visti finora gestiscono interazioni brevi (richiesta-risposta) • Utente 2 chiede titoli film applicazione genera pagina con lista di titoli film • Utente 1 chiede nomi attori applicazione genera pagina con lista nomi • Utente 2 chiede nomi attori applicazione genera pagina con lista nomi, senza tener conto che utente aveva prima chiesto titoli di film. Le due richieste considerate come interazioni separate (e in questo tipo di applicazione non serve correlarle, ma ci sono casi diversi) Laboratorio di Servizi Web - servlet2 - Ardissono
Gestione interazione con utente - I • Per navigazione in pagine statiche non serve memorizzare dati utente • continuazione dell’interazione è data da successione di link seguiti da utente • Es: piccolo libro ipertestuale implementato ad inizio laboratorio come pagine HTML linkate • Per interazioni brevi (richiesta-risposta) non serve memorizzare dati utente (clickstream, dati personali, …) durante interazione • Utente fornisce dati utili mediante compilazione di form e servizio immediatamente invocato passando dati raccolti con form Laboratorio di Servizi Web - servlet2 - Ardissono
Gestione interazione con utente - II • Normali servizi accessibili da web prevedono interazioni complesse e riconoscimento di sequenza di azioni eseguite da utente durante interazione. Es: • apri catalogo (automobili usate), visita pagina di prodotto (berline), visualizza dettagli di auto X (FIAT marea, Alfa 156, Ford mondeo, …) • acquista automobile X (carrello spesa) • Scegli colore auto, cilindrata, … • Scegli optionals • Inserisci dati personali • Inserisci dati carta di credito • … • serve meccanismo per tracciare sequenza di azioni effettuate dallo stesso browser durante interazione inserimento dati può richiedere più passi (compilazioni di form) correlati Laboratorio di Servizi Web - servlet2 - Ardissono
Protocolli di interazione stateless e stateful • Protocollo stateless • Ogni richiesta utente gestita in sessione diversa il server non ha memoria delle precedenti richieste utente • Es: HTTP 1.0 • Protocollo stateful • permette di gestire risposte a richieste che dipendono da contenuto di richiesta e da risultati di precedenti richieste • gestisce un canale (virtuale) di comunicazione che permette di vedere richieste e risposte multiple come parte della stessa connessione tra client e server • Es: FTP, telnet Laboratorio di Servizi Web - servlet2 - Ardissono
Sessione utente e stato di interazione • Sessione utente • Server riconosce richieste successive di stesso browser come parte di una sola interazione • Stato • Server ricorda dati relativi a precedenti richieste effettuate durante la sessione. Può rispondere a richieste tenendo conto di quanto già fatto • Es: mantenimento carrello spesa NB: gestione sessioni utente è necessario per gestire stato, ma non sufficiente Es: HTTP 1.1 supporta sessioni utente ma non stato di interazione Laboratorio di Servizi Web - servlet2 - Ardissono
Tecniche di session tracking - I Basate su scambio di token identificativo tra client (C) e server (S): • C invia richiesta HTTP a S • S risponde associando token univoco T a risposta • C invia ulteriori richieste associando token T, che permette a S di riconoscere C Risposta con token Client C Server S Richiesta con token Laboratorio di Servizi Web - servlet2 - Ardissono
Tecniche di session tracking - II • URL Rewriting • token inserito in URL di richieste eseguite da client • Hidden form fields • token inserito in campi nascosti delle form • Cookies • token inserito in header di HTTP request e response • Sessioni che usano Secure Socket Layer (SSL) • SSL usa protocollo di scambio di messaggi crittografati HTTPS. Per stabilire connessioni, client e server generano session keys (chiavi simmetriche per crittografare e decrittare messaggi). Tali chiavi possono essere usate per identificare client e sessione utente Laboratorio di Servizi Web - servlet2 - Ardissono
URL rewriting • Data HTTP request da client, server • genera token identificativo di client, T • Es: T= 2F392C7084114FADC082D9BA22D81957 • inserisce token come parametro di query in ciascun link presente in pagina di risposta che invia a client: sessionid=T • Es: <a href=“http://www.example.com/servlet/hello;sessionid=2F392C7084114FADC082D9BA22D81957”> link </a> • Così, per ogni link che utente può seguire, HTTP request contiene anche parametro supplementare sessionid, usato da server per riconoscere client Laboratorio di Servizi Web - servlet2 - Ardissono
Browser può disabilitare cookies Cookies • Cookie • informazione testuale inviata da server a client, memorizzata su client e restituita da client a server ad ogni richiesta HTTP • contiene lista di coppie <nome, valore>, con attributi addizionali (come campo commento, massimo tempo di vita del cookie, …) • scambiato tra client e server in header di ciascuna HTTP request e response • Web server invia cookie come segue (es) • Set-cookie: uid=pippo; Domain=“.myserver.com”; Max-age=3600; Path=“/” nome del cookie: uid valore del cookie: pippo attributi: domain, ... Laboratorio di Servizi Web - servlet2 - Ardissono
Session tracking con Servlets (JSP) - I • Servlet utilizzano techniche di session tracking (cookies, URL rewriting, vd dopo) per riconoscere sequenza di azioni provenienti da stesso browser • Servlet offrono infrastruttura per mantenere in modo automatico dati relativi a sessione utente che si vogliono ricordare durante sessione di interazione • permettono session tracking e mantenimento stato di sessione utente • NB: sessioni utente devono scadere secondo timeout per non caricare troppo il server in caso utenti non chiudano esplicitamente sessione Laboratorio di Servizi Web - servlet2 - Ardissono
Session tracking con Servlets (JSP) • Serve strumento per gestire dati relativi a sessione utente (e.g., identificazione utente, stato interazione, …) Applicazione web Web container Servlet/JSP Web server Dati U-session 1 Dati U-session 2 Web browser-1 Web browser-2 Stato interazione: Associato a HTTP requests Laboratorio di Servizi Web - servlet2 - Ardissono
Accessi paralleli a servizio – interazione complessa SERVLET ….. if (operazione.equals(“passo1”) { codice di passo 1 del servizio} else if (operazione.equals(“passo2”) { codice di passo 2 del servizio} else if … else {codice conclusione servizio} ….. stampa pagina di output su PrintWriter chiudi PrintWriter Web server Applicazione Web browser2 Per eseguire codice di passo x potrebbero servire dati acquisiti in passi precedenti di interazione browser1 Laboratorio di Servizi Web - servlet2 - Ardissono
Session tracking con Servlet API • Interfaccia javax.servlet.HttpSession incapsula nozione di sessione utente • Web container implementa HttpSession • Interfaccia HttpServletRequest offre metodo getSession() per accedere oggetto HttpSession associato a richiesta utente (Http Request: GET, POST, …) • HttpRequest • getSession() HttpSession rappresenta sessione utente individuale Laboratorio di Servizi Web - servlet2 - Ardissono
getSession() • se HTTP request non ha oggetto sessione associato (prima richiesta, browser non accetta cookies, ...), getSession() crea nuovo oggetto sessione e lo restituisce al chiamante • altrimenti restituisce oggetto sessione già associato a richiesta in precedente interazione tra client e server da metodi doGet e doPost di Servlet si può accedere a sessione utente interrogando oggetto HttpServletRequest passato come parametro riconoscere utente! Laboratorio di Servizi Web - servlet2 - Ardissono
Interfaccia HttpSession - session tracking • String getId(): restituisce identificativo di sessione (token, es: 2F392C7084114FADC082D9BA22D81957) • long getLastAccessedTime(): restituisce numero di millisecondi trascorsi da ultima richiesta del client • int getMaxInactiveTime(): restituisce numero max di secondi di attività della sessione tra due richieste utente • boolean isNew(): true se sessione è stata creata da server ma client non ha ancora inviato richiesta con session token; false altrimenti • void invalidate(): fa terminare sessione utente (es. per logout) • ….. Laboratorio di Servizi Web - servlet2 - Ardissono
Gestione di sessioni utente – esempio – Life0 • Sviluppiamo una Servlet che mantiene sessione utente per ciascun utente (browser che si collega) • Non salviamo ancora dati utente in oggetto sessione • Imposto tempo massimo tra due richieste di utente pari a 2 minuti • La prima volta che utente invoca applicazione si crea sessione nuova • Se utente invoca di nuovo applicazione (da stesso browser), prima di 2 minuti, si stampano dati di sessione precedente • Se passano più di 2 minuti, creazione di sessione nuova (la precedente è scaduta) Laboratorio di Servizi Web - servlet2 - Ardissono
Esempio - Life0 - I http:130.192.241.1:10000/swebi/servlet/life0 package application.servlets; import javax.servlet.*; import javax.servlet.http.*; import java.io.*; import java.util.*; <servlet> <servlet-name>life0</servlet-name> <description> …. </description> <servlet-class>application.servlets.Life0</servlet-class> </servlet> <session-config> <!-- maxInactiveTime di servlets e JSP dell’applicazione web, in minuti --> <session-timeout>2</session-timeout> </session-config> Se attendo più di 2 minuti tra una invocazione e l’altra ottengo sessione nuova web.xml Laboratorio di Servizi Web - servlet2 - Ardissono
GET: invocazione senza FORM Esempio - Life0 - II public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("<html><head><title>Session” + “Lifecycle 0 </title></head><body>"); HttpSession s = req.getSession(); out.print("<p>Stato della sessione: "); if (s.isNew()) out.println(" nuova sessione</p>"); else out.println(" vecchia sessione</p>"); Recupero oggetto sessione da richiesta HTTP Verifico se nuova sessione o vecchia Laboratorio di Servizi Web - servlet2 - Ardissono
Esempio - Life0 - III out.println("<p>ID di sessione: "+s.getId()); out.println("<br>Data di creazione: " + new Date(s.getCreationTime())); out.println("<br>Max inactive time interval (in secondi): ” + s.getMaxInactiveInterval()); out.println("</p> </body></html>"); out.close(); } } Recupero e stampo informazioni su sessione utente invocando metodi di HttpSession su oggetto sessione Laboratorio di Servizi Web - servlet2 - Ardissono
Ancora session tracking • Web container gestisce • scambi di token tra client e server • associazioni token-oggetti sessione utente • Codice di Servlet accede a sessione utente come oggetto associato a HttpServletRequest • Normalmente session tracking effettuato usando cookies che server invia a browser • Se browser rifiuta cookies, web container può passare a URL rewriting (bisogna invocare metodi specifici) Life0 non fa URL rewriting provare a disabilitare cookies… sessione sempre nuova... Laboratorio di Servizi Web - servlet2 - Ardissono
Gestione di sessioni utente – Life • Sviluppiamo Servlet che mantiene sessione utente per ciascun utente (browser che si collega) • Session tracking basato su URL rewriting • invocazione Servlet come GET con specifica di parametro “action” che indica azione da eseguire • Se action = “invalida” invalido sessione utente • Altrimenti ( “action”= null o action “newSession”) carico pagina che visualizza stato della sessione • Non salviamo ancora dati utente in oggetto sessione • Imposto tempo massimo tra due richieste di utente pari a 2 minuti Laboratorio di Servizi Web - servlet2 - Ardissono
Invalido Laboratorio di Servizi Web - servlet2 - Ardissono
Nuova sessione Laboratorio di Servizi Web - servlet2 - Ardissono
Life - session tracking con URL rewriting http:130.192.241.1:10000/swebi/servlet/life … package e imports… public class Life extends HttpServlet { String url; public Life() { url = ""; } <servlet> <servlet-name>life</servlet-name> <description> Descrizione della servlet di gestione sessioni utente </description> <servlet-class>application.servlets.Life</servlet-class> </servlet> <session-config> <!-- maxInactiveTime di servlets e JSP dell’applicazione web, in minuti --> <session-timeout>2</session-timeout> </session-config> web.xml Laboratorio di Servizi Web - servlet2 - Ardissono
Life - session tracking con URL rewriting - I public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String azione = req.getParameter("action"); res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("<html><head><title>SessionLifecycle” + “</title></head><body>"); HttpSession s = req.getSession(); Leggo azione richiesta: action = null (carica pagina) invalida (termina sessione) newSession (nuova sessione) Laboratorio di Servizi Web - servlet2 - Ardissono
Life - session tracking con URL rewriting - II Faccio terminare sessione if (azione!=null && azione.equals("invalida")) { s.invalidate(); out.println("<p>Sessione invalidata!</p>"); url = res.encodeURL("life"); out.println("<p>Crea nuova <a href=\"" + url + "?action=newSession\">sessione</a></p>"); } Abilito URL rewriting di indirizzo di Servlet (con alias): 130.192.241.1:1000/sweb40/servlet/life;sessionid=484A....?action=newSession Imposto GET con parametro action=“newSession” per nuova invocazione di Servlet Laboratorio di Servizi Web - servlet2 - Ardissono
Life - session tracking con URL rewriting - III else { out.print("<p>Stato della sessione: "); if (s.isNew()) out.println(" nuova sessione</p>"); else out.println(" vecchia sessione</p>"); url = res.encodeURL("life"); out.println("<p>ID di sessione: "+s.getId() + “</p>”); out.println("<p>Invalida <a href=\"" + url + "?action=invalida\">sessione</a></p>"); out.println("<p>Ricarica <a href=\"" + url + "\">pagina</a></p>"); } out.println("</body></html>"); out.close(); } } altri link di chiamata della Servlet Laboratorio di Servizi Web - servlet2 - Ardissono
Interazione con servlet Life • Disabilitando cookies si vede che link di pagine generate da Life includono token di sessione • Riabilitandoli, non si vedono più i token… web container gestisce session tracking via cookies o URL rewriting, a seconda del browser utente • Poichè le maxInactiveTime= 2 minuti, se si attende prima di seguire i link da pagina generata da Servlet si ottiene sessione nuova • Se si segue link invalida, si ottiene sessione nuova • Se si segue link ricarica, entro 2 minuti, si ottiene sessione vecchia Laboratorio di Servizi Web - servlet2 - Ardissono
Interfaccia HttpSession - stato sessione utente Oggetto HttpRequest può contenere anche attributi associati a sessione utente Tali attributi sono usati per mantenere informazioni su stato della particolare sessione utente • void setAttribute(String attrName, Object attr): salva attr, con nome attrName, in oggetto sessione • Es: s.setAttribute(String “nome”, “pippo”) • NB: potrei salvare oggetto complesso (e.g., Hashtable) con molti dati utente • Object getAttribute(String attrName): restituisce oggetto associato a nome attrName in sessione utente • Es: s.getAttribute(“nome”) Object che contiene stringa “pippo” Laboratorio di Servizi Web - servlet2 - Ardissono
Accesso ad attributi di sessione utente • setAttribute() mantiene riferimento a oggetto java se riferimento cambia bisogna rieseguire il metodo (non se cambiano i campi dell’oggetto…) • esiste anche removeAttribute() per rimuovere attributo da sessione utente • getAttribute(), setAttribute() e removeAttribute()non sono synchronized se più thread cercano di modificare una stessa sessione utente si possono avere problemi gestire mutua esclusione Laboratorio di Servizi Web - servlet2 - Ardissono
Servlet stateful - esempio • Stato di sessione utente può includere attributi che contengono valori • Attributi usati per salvare valori di dati acquisiti durante interazione che si vogliono mantenere fino a fine interazione (es. Nome utente, dati personali, …) • Sviluppiamo Servlet (life2) invocata da FORM HTML con cui utente inserisce dati da usare nell’applicazione Laboratorio di Servizi Web - servlet2 - Ardissono
Interazione con Servlet stateful - life2 http:130.192.241.1:10000/swebi/stato.html <HTML><HEAD> …. </HEAD> <BODY> <center> <FORM ACTION="servlet/life2" METHOD="POST" > <table align="center" width="100%" cellspacing="2" cellpadding="2"> <tr> <td align="right">Login:</td> <td><input type="text" name="login" align="left" size="25"></td> </tr> <tr> <td align="right">Password:</td> <td><input type="password" name="passwd" align="left" size="25"></td> </tr> </table> <CENTER> <INPUT TYPE="Submit" NAME="btnSubmit" VALUE="Submit request"> </CENTER> </FORM> </BODY></HTML> Laboratorio di Servizi Web - servlet2 - Ardissono
Invalido Laboratorio di Servizi Web - servlet2 - Ardissono
Nuova sessione Laboratorio di Servizi Web - servlet2 - Ardissono
Ricarico pagina Laboratorio di Servizi Web - servlet2 - Ardissono
Life2 - session tracking con stato Metodo doPost serve per gestire richiesta da form stato.html …package e imports… public class Life2 extends HttpServlet { String url = “”; public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String loginName = req.getParameter("login"); HttpSession s = req.getSession(); // salvo login utente come attributo in stato di sessione if (loginName!=null) s.setAttribute("account", loginName); …. Salvo nome di login in stato della sessione Laboratorio di Servizi Web - servlet2 - Ardissono
Life2 - I … prendo PrintWriter e stampo prima parte di pagina … out.print("<p>Stato sessione: "); if (s.isNew()) { stampo nuova sessione e loginName; } else { out.println(" vecchia sessione:<br>"); Object l = s.getAttribute("account"); if (l!=null) out.println(" login utente: "+l.toString() + “</p>”); else out.println(" utente sconosciuto </p>"); } url = res.encodeURL("life2"); out.println("<p>ID di sessione: "+s.getId()); out.println("<br>Creazione: "+new Date(s.getCreationTime()) + “</p>”); out.println("<p>Invalida <a href=\"" + url + "?action=invalida\">sessione</a></p>"); out.println("<p>Ricarica <a href=\"" + url + "\">pagina</a></p>"); out.println("</body></html>"); out.close(); } Laboratorio di Servizi Web - servlet2 - Ardissono
NB: doGet + doPost • Servlet life2 deve poter gestire richieste: • da form HTML (POST) • da link in pagina HTML (GET): es. Ricarica pagina, invalida sessione,… • non basta implementare metodo doPost: bisogna anche implementare metodo doGet • A seconda del tipo di chiamata (da form, da click su link ipertestuale) eseguito metodo opportuno Laboratorio di Servizi Web - servlet2 - Ardissono
Life2 - II public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { … prendo PrintWriter e stampo prima parte di pagina … String azione = req.getParameter("action"); HttpSession s = req.getSession(); if (azione!=null && azione.equals("invalida")) { s.invalidate(); out.println("<p>Sessione invalidata!</p>"); url = res.encodeURL("life2"); out.println("<p>Crea nuova <a href=\"" + url + "?action=newSession\">sessione</a></p>"); } Metodo doGet serve per gestire richieste GET da pagine generate da Servlet Laboratorio di Servizi Web - servlet2 - Ardissono
Metodo doGet è relativamente simile a doPost perchè bisogna generare pagine simili tra loro (utente non deve accorgersi di differenze in UI) Life2 - III else { out.print("<p>Stato della sessione: "); if (s.isNew()) { out.println(" nuova sessione</p>"); Object l = s.getAttribute("account"); if (l!=null) stampo login utente; else stampo utente sconosciuto; } else { stampo vecchia sessione; ricavo login utente da stato e lo stampo; else stampo utente sconosciuto; out.println("</p>"); } Laboratorio di Servizi Web - servlet2 - Ardissono
Life2 - IV url = res.encodeURL("life2"); out.println("<p>ID di sessione: "+s.getId()); out.println("<br>Data di creazione: "+new Date(s.getCreationTime())); out.println("</p>"); out.println("<p>Invalida <a href=\"" + url + "?action=invalida\">sessione</a></p>"); out.println("<p>Ricarica <a href=\"" + url + "\">pagina</a></p>"); } out.println("</body></html>"); out.close(); } // chiusura metodo doGet } // chiusura Servlet Laboratorio di Servizi Web - servlet2 - Ardissono
Riassumendo - contesto di applicazione • insieme di parametri di configurazionecomuni a tutte le Servlet e JSP che appartengono all’applicazione • Es: session-timeout che specifica maxInactiveTime • include dichiarazioni di Servlet e JSP (es: alias per invocazione, …) • si possono anche salvare nel contesto attributi, che rappresentano lo stato dell’applicazione intera e possono essere usati da Servlet e JSP per recuperare dati su stato dell’applicazione, ma non lo vediamo Laboratorio di Servizi Web - servlet2 - Ardissono
Riassumendo - sessione utente • Associata a token identificativo di utente • Oggetto complesso, può mantenere attributi che rappresentano stato di sessione utente • Accessibile da ogni oggetto di tipo HTTPRequest Servlet può aggiornare stato man mano che gestisce richieste utente • Nel nostro esempio abbiamo gestito uno stato che includeva solo l’account dell’utente; in generale, lo stato può essere molto più complesso, es., shopping cart di negozio elettronico Laboratorio di Servizi Web - servlet2 - Ardissono
Collaborazione tra Servlet - I • Esempi visti: servizio implementato da una sola Servlet (es, Life, Life2, Informazioni, ...). Servlet • riceve richiesta (GET o POST) • esegue metodo (doGet, doPost) per gestire richiesta e preparare risposta (pagina html) • restituisce risposta a web server • MA, una Servlet può invocare altre Servlet (o JSP) per svolgere parte del servizio. Per esempio: • invocazione di altra servlet per creazione di porzione fissa di pagina • invocazione di JSP per generazione pagina risposta • Invocazione di pagina statica HTML!! • ... Laboratorio di Servizi Web - servlet2 - Ardissono
Collaborazione tra servlet - II Response BannerGen include Utente registrato support.html TechSupport POST Servlet diverse forward Utente non registrato register.html Register POST Laboratorio di Servizi Web - servlet2 - Ardissono
Request dispatching - I • Permette di redirigere (forward) una HTTP request ad altra Servlet/JSP/pagina HTML • Destinatario del forward si occupa di gestire richiesta • Per redirigere richiesta serve riferimento ad altra entità (risorsa web) • Interfaccia RequestDispatcher incapsula tale riferimento e può essere usato per invocare altre risorse (le rappresenta) Laboratorio di Servizi Web - servlet2 - Ardissono