Newsgroup: it.comp.java
Titolo: Intercettare fine sessione in Tomcat

Sto facendo un'applicazione web in jsp/servlet che gira su Tomcat. Voglio
controllare chi si collega e da dove perchè l'applicazione gira sia sulla
nostra intranet che su internet. Il mio problema è sapere quando uno si
scollega. Ho messo un pulsante per scollegarsi ma in pochi lo usano, molti
chiudono il browser con la x. Mi piacerebbe comunque intercettare quando
Tomcat uccide la sessione perchè l'utente non ci lavora più per un tempo
superiore la timeout.
E' possibile? Se si come?
Grazie.
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

Puoi inserire del codice javascript che gestisca l'evento onUnload della
pagina e invii l'informazione al server, non mi risulta ci siano altri
metodi a parte il timeout della sessione che comunque non ha a che fare con
la chiusura della pagina ma con il tempo trascorso dall'ultima interazione
fra client e server.
*************************************************
Niko
-----------------------------------------------------------------
Ci sono 10 categorie di persone al mondo: quelle che capiscono
il sistema binario e quelle che non lo capiscono.

 Niko



> E' possibile? Se si come?
Ci sono tutta una serie di classi "listener" indicate dalla specifica dei
servlet: se leggi la documentazione (javadoc) le trovi con facilità. Ora non
ricordo con esattezza i nomi, ma sono cose come HttpSessionListener,
HttpSessionBindingListener, ecc. Puoi tracciare non solo gli eventi di
scadenza di una sessione, ma anche gli eventi di aggiunta o rimozione
attributi dalla sessione, ecc. Alcuni di questi oggetti "funzionano" solo
implementando particolari interfacce: per i session listener credo che tu
debba definire un oggetto nel web.xml della applicazione che stai scrivendo.


Affrontai lo stesso problema qualche tempo fa. Se hai degli oggetti
associati alla sessione (quindi all'utente che si logga), basta che
ridefinisci il metodo protected void finalize() che tutti gli oggetti
ereditano da Object. Nel corpo del metodo gli fai fare le operazioni che ti
pare (che so, settare un campo "logged_in" del Database a 'N', per esempio).
Quando il Garbage Collector distrugge l'oggetto (operazione che effettua
allo scadere della sessione), ne invoca il metodo finalize().
Se vuoi un metodo più "elegante" puoi dare un'occhiata ai
SessionBindingListener (non ricordo se il nome della classe è proprio
quello, comunque spulciando la documentazione J2EE dovresti trovarlo).
Ciao

 quello, comunque spulciando la documentazione J2EE dovresti trovarlo).
Appunto!


AZZolina, questo non lo sapevo.
In particolare, per quale(i) motivo(i) non è garantito che vengano
chiamati??

 ha scritto nel messaggio
news:b56pt0$o6s$1...@news.newsland.it...


 chiamati??
beh, ad esempio perché non gira la garbage collection! La gc gira se e solo
se "ce n'è bisogno" (o se la forzi), e quindi non hai garanzie sul se e sul
quando: non è certo vero, ad esempio, che nel momento in cui scarti
l'oggetto che rappresenta la sessione, cioè annulli tutti i riferimenti che
vi puntano, il tempo che passerà da quel momento a quando l'oggetto viene
fisicamente "raccolto" dal collector sarà "poco": questo invalida la
possibilità di usare il finalize per marcare in qualche modo l'evento di
fine della sessione! Di più: ricordo di aver sentito parlare di alcune
implementazioni "old style" di java che, sfruttando alcune fumosità della
specifica, non chiamavano proprio i finalizzatori (ma non vorrei fosse una
leggenda). Guarda quello che dice questo "tip", ad esempio
(
http://developer.java.sun.com/developer/TechTips/2000/tt0124.html
):
The purpose of the Finalize method is often misunderstood by programmers.
The Javadoc comment for Finalize states that it's called by the garbage
collector on an object when the garbage collector determines that there are
no more references to the object. Presumably the garbage collector will,
like its civil servant namesake, visit the heap on a regular basis to clean
up resources that are no longer in use.
As reasonable as it may seem, this interpretation of finalization relies on
assumptions about garbage collection that are not supported by the Java
language specification. The primary purpose of Java garbage collection is
not to run finalizers. Garbage collection exists to prevent programmers from
calling delete. This is a wonderful feature. For example, if you can't call
delete, then you can't accidentally call delete twice on the same object.
However, removing delete from the language is not the same thing as
automatically cleaning up. The name "garbage collection" promises too much.
Confusion might have been saved by using the name "delete prevention"
instead. In fact, the Java garbage collection specification imposes only
minimal requirements for the behavior of garbage collection, which include:
  1.. Garbage collection might not ever run. If garbage collection runs at
all, and an object is no longer referenced, then that object's finalize will
run.
  2.. Across multiple objects, finalize order is not predictable.
Either of these rules, taken alone, would be enough to make finalize a risky
way to clean up resources. So why do developers leap to the wrong conclusion
and rely on finalize? There are two reasons: they are swayed by the analogy
to the C++ destructor, and they often get away with it in the short run.
Combine a simple project with a better-than-average VM implementation, and
finalize will appear almost as reliable as a C++ destructor. Don't be fooled
by this temporary good luck. If you rely on finalize, your code will not
scale to larger projects, and it will not run consistently on different
virtual machines.
The correct approach to resource cleanup in Java language programs does not
rely on finalize. Instead, you simply write explicit close methods for
objects that wrap native resources. If you take this approach, you must
document that the close method exists and when it should be called. Callers
of the object must then remember to call close when they are finished with a
resource.
This probably does not live up to your hopes for garbage collection, since
you are back to the manual labor of freeing resources yourself. Moreover,
this code still has a problem: if an exception is thrown from somewhere
inside the method that calls close, the close method will never be reached.
This calls for a way to force a code block to be executed, regardless of
exceptions. Java's finally clause fits the bill perfectly. After any try
block in Java, you can specify a finally block which will execute, no matter
how the try block exits--either normally or exceptionally.
A parte quello che c'è scritto qui, siccome i finalizer vengono lanciati in
qualche modo "dal garbage collector", se l'implementazione del gc li fa
girare "durante", la garbage collection, ovvero durante la sua parte
BLOCCANTE (in cui la tua applicazione è completamente ferma), tu aumenti il
periodo di stop, mettendo nei finalizzatori del codice. Tra l'altro, siccome
nel finalize potrebbe esserci del codice che rende nuovamente "utilizzato"
l'oggetto che stai finalizzando, la virtual machine deve controllare, DOPO
che il finalizzatore è girato, se l'oggetto è ancora "morto": questo quindi
aumenta la durata di vita degli oggetti con finalizzatore, e peggiora il
consumo di memoria della tua applicazione. Guarda ad esempio cosa dicono in
questo capitolo:
http://developer.java.sun.com/developer/Books/performance/performance2/appen
dixa.pdf

Non c'è che dire, mi hai convinto appieno.
Ciao
:)

Grazie 1000 a tutti
