ServletContext
All'avvio del contenitore servlet (come Apache Tomcat ), verrà distribuito e caricato tutte le sue applicazioni Web. Quando viene caricata un'applicazione Web, il contenitore servlet crea ServletContextuna volta e la mantiene nella memoria del server. La web app web.xmle tutti inclusi web-fragment.xmlviene analizzato i file, e ciascuno <servlet>, <filter>e <listener>hanno trovato (o ogni classe annotati con @WebServlet, @WebFiltere @WebListenerrispettivamente) viene istanziato una volta e mantenute in memoria del server pure. Per ogni filtro istanziato, il suo init()metodo viene richiamato con un nuovo FilterConfig.
Quando a Servletha un valore <servlet><load-on-startup>o @WebServlet(loadOnStartup)maggiore di 0, il suo init()metodo viene anche richiamato durante l'avvio con un nuovo ServletConfig. Tali servlet sono inizializzati nello stesso ordine specificato da quel valore ( 1è il 1o, 2è il 2o, ecc.). Se lo stesso valore è specificato per più di una servlet, allora ogni servlet viene caricato nello stesso ordine in cui appaiono nella web.xml, web-fragment.xmlo @WebServletclassloading. Nel caso in cui il valore "load-on-startup" sia assente, il init()metodo verrà invocato ogni volta che la richiesta HTTP raggiunge quel servlet per la prima volta.
Al termine del contenitore servlet con tutte le fasi di inizializzazione sopra descritte, ServletContextListener#contextInitialized()verrà richiamato.
Quando gli chiude servlet container verso il basso, esso scarica tutte le applicazioni web, invoca il destroy()metodo per tutti i suoi servlet e filtri inizializzati, e tutti ServletContext, Servlet, Filtere Listeneristanze vengono cestinati. Alla fine ServletContextListener#contextDestroyed()verrà invocato.
HttpServletRequest e HttpServletResponse
Il contenitore servlet è collegato a un server Web che ascolta le richieste HTTP su un determinato numero di porta (la porta 8080 viene generalmente utilizzata durante lo sviluppo e la porta 80 in produzione). Quando un client (ad esempio, utente con un browser web, o di programmazione utilizzandoURLConnection ) invia una richiesta HTTP, il contenitore di servlet crea nuovi HttpServletRequeste HttpServletResponseoggetti e li passa attraverso qualsiasi definita Filterdella catena e, infine, l' Servletistanza.
Nel caso dei filtri , doFilter()viene invocato il metodo. Quando il codice del contenitore servlet chiama chain.doFilter(request, response), la richiesta e la risposta continuano al filtro successivo oppure premere il servlet se non ci sono filtri rimanenti.
Nel caso dei servlet , service()viene invocato il metodo. Per impostazione predefinita, questo metodo determina quale dei doXxx()metodi da richiamare in base request.getMethod(). Se il metodo determinato è assente dal servlet, viene restituito un errore HTTP 405 nella risposta.
L'oggetto richiesta fornisce l'accesso a tutte le informazioni sulla richiesta HTTP, come URL, intestazioni, stringa di query e corpo. L'oggetto response offre la possibilità di controllare e inviare la risposta HTTP nel modo desiderato, ad esempio, consentendo di impostare le intestazioni e il corpo (di solito con contenuto HTML generato da un file JSP). Una volta eseguito il commit e il completamento della risposta HTTP, gli oggetti richiesta e risposta vengono riciclati e resi disponibili per il riutilizzo.
HttpSession
Quando un client visita la webapp per la prima volta e / o HttpSessionviene ottenuto per la prima volta tramite request.getSession(), il contenitore servlet crea un nuovo HttpSessionoggetto, genera un ID lungo e univoco (che è possibile ottenere session.getId()) e lo memorizza nel server memoria. Il contenitore servlet imposta anche Cookiea Set-Cookienell'intestazione della risposta HTTP con JSESSIONIDcome nome e l'ID sessione univoco come valore.
Secondo la specifica del cookie HTTP (un contratto a cui devono aderire qualsiasi browser Web e server Web decente), il client (il browser Web) è tenuto a rispedire questo cookie nelle richieste successive Cookienell'intestazione fintanto che il cookie è valido ( cioè l'ID univoco deve fare riferimento a una sessione non scaduta e il dominio e il percorso sono corretti). Utilizzando il monitoraggio del traffico HTTP integrato nel browser, è possibile verificare che il cookie sia valido (premere F12 in Chrome / Firefox 23+ / IE9 + e controllare la scheda Rete / Rete ). Il contenitore servlet controllerà l' Cookieintestazione di ogni richiesta HTTP in entrata per la presenza del cookie con il nome JSESSIONIDe utilizzerà il suo valore (l'ID sessione) per ottenere l'associato HttpSessiondalla memoria del server.
Le HttpSessionrimane attivo fino stato inattivo (cioè non utilizzato in una richiesta) per più del valore di timeout specificato <session-timeout>, un'impostazione web.xml. Il valore di timeout viene impostato automaticamente su 30 minuti. Pertanto, quando il client non visita l'app Web per un periodo di tempo superiore a quello specificato, il contenitore servlet trascina la sessione. Ogni richiesta successiva, anche con il cookie specificato, non avrà più accesso alla stessa sessione; il contenitore servlet creerà una nuova sessione.
Sul lato client, il cookie di sessione rimane attivo fino a quando l'istanza del browser è in esecuzione. Pertanto, se il client chiude l'istanza del browser (tutte le schede / finestre), la sessione viene spostata sul lato client. In una nuova istanza del browser, il cookie associato alla sessione non esisterebbe, quindi non verrebbe più inviato. Ciò provoca la HttpSessioncreazione di un tutto nuovo, con l'utilizzo di un cookie di sessione completamente nuovo.
In poche parole
- La
ServletContextvita finché dura l'app web. È condiviso tra tutte le richieste in tutte le sessioni.
- Le
HttpSessionvite per tutto il tempo come il client interagisce con il web app con la stessa istanza del browser, e la sessione non è scaduta al lato server. È condiviso tra tutte le richieste nella stessa sessione.
- L'
HttpServletRequeste HttpServletResponsediretta dal momento in cui la servlet riceve una richiesta HTTP da parte del cliente, fino a quando la risposta completa (la pagina web) è arrivato. E ' non è condivisa altrove.
- Tutti
Servlet, Filtere Listenerle istanze vivere fintanto che l'applicazione web vive. Sono condivisi tra tutte le richieste in tutte le sessioni.
- Qualsiasi
attributeche è definita in ServletContext, HttpServletRequeste HttpSessionvivrà fino a quando l'oggetto in questione vite. L'oggetto stesso rappresenta lo "scopo" nei framework di gestione dei bean come JSF, CDI, Spring, ecc. Tali framework memorizzano i loro bean con scope come uno attributedei suoi scopi di corrispondenza più vicini.
Sicurezza del filo
Detto questo, la tua principale preoccupazione è probabilmente la sicurezza del thread . Ora dovresti sapere che servlet e filtri sono condivisi tra tutte le richieste. Questa è la cosa bella di Java, è multithread e diversi thread (leggi: richieste HTTP) possono usare la stessa istanza. Altrimenti sarebbe troppo costoso ricrearli init()e destroy()loro per ogni singola richiesta.
Dovresti anche capire che non dovresti mai assegnare alcuna richiesta o dati nell'ambito della sessione come variabile di istanza di un servlet o filtro. Sarà condiviso tra tutte le altre richieste in altre sessioni. Quello è non thread-safe! L'esempio seguente illustra questo:
public class ExampleServlet extends HttpServlet {
private Object thisIsNOTThreadSafe;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object thisIsThreadSafe;
thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests!
thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe.
}
}
Guarda anche: