Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Gestire le sessioni con JSP e Servlet

Alcuni metodi per tenere traccia delle sessioni nelle applicazioni web
Alcuni metodi per tenere traccia delle sessioni nelle applicazioni web
Link copiato negli appunti

La gestione delle sessioni (session tracking) rappresenta, certamente, uno dei punti cruciali di un'applicazione web. Gran parte dei siti che basano la propria fortuna sull'e-commerce, ad esempio, incontrerebbero non poche difficoltà se non fosse possibile riuscire a tenere traccia delle molteplici sessioni con i vari client che interagiscono con essi.

L'esempio classico del carrello virtuale della spesa è il simbolo, forse, più rappresentativo di questa importante funzionalità. Ma andiamo per gradi, iniziando a chiarire innanzitutto il concetto di sessione.

Cos'è una Sessione?

Tenere traccia degli utenti durante la navigazione su un determinato sito rappresenta quello che, tecnicamente, viene definito "Sessione Web". Ad esempio, riallacciandoci al caso sopra citato del carrello virtuale della spesa, tenere traccia di un utente su un sito di e-commerce vorrà dire, tra le altre cose, non perdere le informazioni relative agli articoli già scelti per l'acquisto durante la navigazione (e consentire all'utente stesso di poter scegliere ulteriori articoli) tra una pagina e l'altra.

I neofiti del Web potrebbero trovare una simile funzionalità del tutto scontata e, magari, anche banale ma se andiamo ad esaminare più da vicino il protocollo HTTP ci si accorge che così non è.

I limiti del protocollo HTTP

L'HTTP è noto per essere un protocollo senza stati (stateless protocol) a differenza, ad esempio, dell'FTP che è un protocollo che tiene traccia degli stati (stateful protocol). Ciò vuol dire che, in generale, se un browser richiede una specifica pagina web situata su un determinato web server, quest'ultimo, dopo aver soddisfatto la richiesta, chiude la connessione con il client e non conserva alcuna informazione sul client stesso. Pertanto, se lo stesso browser dovesse effettuare successive richieste allo stesso web server, questo non avrebbe alcun modo per associare il browser con le richieste pervenute in precedenza.

Figura 1. Colloquio client/server con HTTP
Colloquio client/server con HTTP

La tecnica utilizzata in Java

Dunque, qual è il metodo utilizzato in Java per sopperire ai limiti del protocollo HTTP e tenere traccia delle sessioni? Guardiamo la seguente figura:

Figura 2. Colloquio client/server con HTTP e Java
Colloquio client/server con HTTP e Java

Ciò che è illustrato nella figura precedente può essere così riassunto: Il browser richiede una pagina JSP o una Servlet inoltrando la richiesta ad un web server. Quest'ultimo non fa altro che passare la richiesta stessa al servlet engine, il quale controlla se la request pervenuta includa o meno un ID per la sessione. Se così non è, il Servlet Engine crea un identificativo univoco, istanziando anche un "session object" ad esso correlato che possa essere utilizzato per salvare i dati utili alla sessione.

Da questo momento in poi il server utilizzerà l'ID di sessione (session ID) per mettere in relazione ogni richiesta del browser con l'opportuno oggetto di sessione precedentemente creato. Si noti che tutto questo avviene senza minimamente intaccare la logica stateless del protocollo HTTP, il quale continuerà a considerare chiusa la connessione con il client dopo aver soddisfatto ogni richiesta pervenuta.

Per default viene utilizzato un cookie per il salvataggio del session ID sul browser del client. In tal modo ad ogni successiva richiesta del browser verrà accodato alla request, l'ID prelevato dal cookie.

L'utilizzo dei cookie, però, non rappresenta una soluzione sempre valida e attuabile. Il problema, infatti, sorge quando vengono disabilitati i cookie sul browser ed il client si trova impossibilitato a salvare il session ID. In tal caso, senza l'utilizzo di una soluzione alternativa la gestione delle sessioni non funzionerebbe.

La soluzione alternativa più efficace è nota come URL encoding e fornisce un modo per riscrivere le URL in modo che esse contengano al loro interno anche il session ID. Grazie all'URL encoding è possibile tenere traccia delle sessioni anche nei casi in cui un utente abbia deciso di disabilitare i cookie sul proprio browser.

I metodi più comuni dell'oggetto Sessione

È facile, in Java, ottenere un riferimento ad un session object. Nelle pagine JSP, session è un oggetto implicito mentre nelle Servlet sarà sufficiente utilizzare il metodo getSession() dell'oggetto implicito request per ottenere un riferimento ad un oggetto di tipo HttpSession:

HttpSession session = request.getSession(); // metodo dell'oggetto request

Attraverso il metodo getSession() verrà restituito l'oggetto di tipo HttpSession relativo alla sessione corrente, qualora ne esista già una. Nel caso in cui non fosse presente alcuna sessione, tale metodo si occuperà di crearne una nuova.

I tre metodi classici utilizzati per lavorare con eventuali attributi del session object sono i seguenti:

  • public void setAttribute(String name, Object value)
  • public Object getAttribute(String name)
  • public void removeAttribute(String name)

Il primo consente di impostare un oggetto Java come attributo di una sessione, assegnandogli un nome. Ad esempio:

session.setAttribute("codiceArticolo", itemCode);

Il secondo metodo permette di ricavare il valore di un attributo fornendo in input il nome dell'attributo stesso. Poiché il tipo restituito è di classe Object sarà necessario effettuare un casting per convertire il risultato al tipo desiderato. Ad esempio:

String itemCode = (String) session.getAttribute("codiceArticolo");

Infine, il metodo removeAttribute() elimina un attributo dal session object, fornendo in input al metodo stesso il nome dell'attributo da rimuovere. Ad esempio:

session.removeAttribute("codiceArticolo");

Nota: Se si lavora con una versione vecchia delle Servlet API (precedente alla 2.2) sarà possibile notare come le impostazioni degli attributi di sessione venivano effettuate attraverso i metodi putValue(), getValue() e removeValue(). Tali metodi, nelle nuove release, sono deprecati e non vanno più utilizzati.

.

Altri metodi comunemente utilizzati per lavorare con le sessioni sono i seguenti (tutti appartenenti all'oggetto sessione):

  • public Enumeration getAttributeNames(): Restituisce un oggetto di tipo java.util.Enumeration che contiene i nomi di tutti gli attributi contenuti nell'oggetto HttpSession. Tale metodo va utilizzato al posto del deprecato getValueNames() che, invece, restituisce un array di Stringhe. Ad esempio:

    Enumeration attrNames = session.getAttributeNames();
    while (attrNames.hasMoreElements())
    {
      // Stampa i nomi di tutti gli attributi di sessione
      System.out.println((String) attrNames.nextElement());
    }

  • public String getId(): Restituisce l'identificativo univoco di sessione generato dal Servlet Engine.
  • public boolean isNew(): Restituisce true se il client non è ancora entrato in sessione oppure se il client stesso è impossibilitato ad utilizzare le sessioni (ad esempio, nel caso in cui i cookie fossero disabilitati e non sia stata prevista una modalità alternativa, come il metodo di URL encoding).
  • public void setMaxInactiveInterval(int seconds): Consente di impostare il numero massimo di secondi di inattività trascorsi i quali la sessione viene terminata. Il valore di default è di 1800 secondi (30 minuti). È, altresì, possibile creare una sessione che prescinda dal numero di secondi di inattività e che resti attiva fino a quando non venga chiuso il browser. In tal caso, il parametro da passare al metodo setMaxInterval è -1.
  • public void invalidate(): Annulla una sessione e rimuove eventuali oggetti salvati nel session object.

Il metodo di URL Encoding

Nonostante la maggior parte dei browser siano impostati per consentire l'utilizzo dei cookie, può accadere di imbattersi in determinati client in cui tale utilizzo sia stato inibito. Abbiamo già detto che, in questi casi la gestione delle sessioni (quella adottata per default) non funzionerebbe a causa della impossibilità di salvare in locale l'ID di sessione.

In determinate circostanze, una simile limitazione potrebbe non essere un problema bloccante, soprattutto se la parte applicativa non rappresenta una sezione critica del sito web. In tal caso, potrebbe essere sufficiente informare l'utente, con un messaggio, che determinate funzionalità del sito non saranno attive a causa della disabilitazione dei cookie.

In molti altri casi, però, l'impossibilità di tenere traccia delle sessioni rappresenta un problema molto più serio. In tal caso, sarà possibile arginare il problema utilizzando il metodo dell'URL Encoding.

È importante, a tal proposito, fare una precisazione: spesso tale metodo è anche denominato come "URL Rewriting", in quanto consente, attraverso l'invocazione di un particolare metodo, la riscrittura della URL di destinazione. Riteniamo, tuttavia, sia più corretto dividere le due definizioni identificando con URL Rewriting un concetto più che altro utile per il passaggio di parametri tra il browser ed il server, come vedremo più avanti.

Sicuramente, però, non va confuso (come spesso capita a molti programmatori) l'URL Encoding che consente di gestire le sessioni, con la funzionalità offerta dalla classe java.net.URLEncoder che permette di convertire, grazie al metodo encode(), determinati caratteri presenti sulla URL (come ad esempio gli spazi) in una notazione accettata dai browser.

Condizione necessaria affinché l'URL Encoding possa essere usato con successo è che tutte le eventuali pagine HTML presenti sul sito siano convertite in altrettante pagine JSP. Lo scopo dell'URL Encoding è quello di aggiungere il session ID ad ogni URL facente capo ad un determinato sito, ogniqualvolta questa venga richiesta attraverso il browser. Per far ciò viene utilizzato il metodo encodeURL() dell'oggetto implicito response, così definito:

public String encodeURL (String url)

Per impostare la action di una pagina JSP in modo che invochi una determinata servlet, ad esempio, si dovrà utilizzare la seguente sintassi:

<%
  String url = response.encodeURL("../servlet/MyServlet");
%>
<form action="<%=url%>" method="post">

È importante ricordarsi di utilizzare il metodo urlEncode() su tutte le URL utilizzate all'interno dell'applicazione web che vengano invocate direttamente da una richiesta del browser (non serve, infatti, utilizzare il metodo urlEncode() nel caso in cui venga inoltrata una richiesta con il metodo forward()).

Infatti, se ci si scordasse di inserirne qualcuna lo scotto da pagare sarebbe quello di perdere traccia della sessione, con tutti i rischi che ne conseguirebbero.

Da sottolineare, infine, il fatto che il metodo di Url Encoding viene utilizzato soltanto quando necessario. Ovvero, se l'applicazione interagisce con un browser in cui sia consentito l'utilizzo dei cookie, verrà utilizzato il metodo di default che scrive il session Id, appunto, su un cookie senza passarlo,quindi, alle URL del sito.

URL Rewriting e hidden fields

L'URL Rewriting e i campi nascosti (hidden fields) rappresentano metodi utili per passare dati tra le varie pagine di un sito. L'URL Rewriting, al contrario dell'URL Encoding visto in precedenza, non utilizza le API messe a disposizione da Java per gestire la propria funzionalità. La sintassi da utilizzare per l'URL Rewriting è la seguente:

url?parametro1=valoreParametro1¶metro2=valoreParametro2...

Ad esempio, un link corrispondente alla scelta di un certo articolo, su un sito di e-commerce potrebbe essere il seguente:

<a href="../servlet/MyServlet?itemCode=2000">Aggiungi al carrello</a>

Anche l'URL Rewriting ha il pregio di lavorare bene sui browser in cui siano stati disabilitati i cookie. Nonostante questo, però, è bene fare attenzione a non abusare di questa tecnica in quanto la maggior parte dei browser limita il numero massimo di caratteri consentiti su una URL a 2000.

Oltretutto, poiché l'URL Rewriting lavora soltanto con il metodo HTTP GET, tutte le variabili passate sulla URL saranno sempre visibili sulla barra degli indirizzi del browser, il che non rappresenta certamente una garanzia di sicurezza e riservatezza dei dati.

Infine, qualche parola sugli hidden fields. Come si intuisce dal nome stesso, essi non sono altro che dei campi nascosti in cui è possibile inserire dei parametri da comunicare al server. Ad esempio:

<form action="../servlet/MyServlet" method="post">
  <input type="submit" value="Aggiungi al carrello" />
  <input type="hidden" name="itemCode" value="2000" />
</form>

Il vantaggio degli hidden fields, rispetto all'URL Rewriting, consiste nel fatto che è possibile utilizzare il metodo HTTP POST, bypassando, così, il problema dello spazio limitato a 2000 caratteri.

Alla prossima.

Ti consigliamo anche