HttpSession expired vs. invalidated

C

christoph

Hi,

I have a session holding user data of an online survey. When the survey
is completed, all data is written to a result file. After that the
session is manually invalidated (servlet calling the invalidate
method).

If the respondent does not complete the interview the session times out
at some point. I would like to flush the data I have in the session so
far to a special result file.

Is there a way of reacting to session expiration (by the server) and
not to invalidation (by the servlet)?

Using HttpSessionListener.sessionDestroyed(HttpSessionEvent se) does
not work, because the data of HttpSessionEvent.getSession() is not
accessible any more when the event is fired. Furthermore the
HttpSessionEvent is fired when the session expires and when the session
is manually invalidated.

Does anyone have advice?

THX,

Chris
 
C

christoph

Hi Andrea,

thx for your reply.
You will have to do that by yourself, keeping track of the sessions
you invalidate.
ok, I could do that
For the data, try the session binding listener
To use this I would have to bind every single value that is stored in
the session. On expiration I would have to save every single value.
There must be a better way.

Yours,

Chris
 
S

Sudsy

To use this I would have to bind every single value that is stored in
the session. On expiration I would have to save every single value.
There must be a better way.

There is: the data should be encapsulated in a single object which can
then be serialized when the session is unbound.
 
A

Andrea Desole

looking at the documentation I found out that there is another listener,
HttpSessionAttributeListener, which might be easier to use.
I don't have a better solution, but if you are keeping track of the
sessions you invalidate, I would say that it might be better to keep
track of the sessions that don't have to be saved. So you can do this:

if a session is invalidated, you register it as a "non save" session,
for exemple by putting its id in a set
if a session expires its attributes will be removed. When the first
attribute is removed you check if the session is in the set. If not, you
can dump all the session attributes, and then add the session to the
set. If the session is already in the set you do nothing.
when the session is destroyed you remove the session from the set.

A bit complex maybe, but it should do the job
 
C

christoph

Hi Andrea,
When the first attribute is removed .... you can dump all the session
attributes ...
This is not possible, because when the HttpSessionBindingEvent is
received, all attributes are already removed from the session and are
not accesible any more :(

To me dumping session variables on expiration seems to be a pretty
normal usecase, I can't believe there is no easy way of doing that.
Chris
 
C

christoph

Hi Andrea,
When the first attribute is removed .... you can dump all the session
attributes ...
This is not possible, because when the HttpSessionBindingEvent is
received, all attributes are already removed from the session and are
not accesible any more :(

To me dumping session variables on expiration seems to be a pretty
normal usecase, I can't believe there is no easy way of doing that.
Chris
 
S

Sudsy

Hi Andrea,



attributes ...
This is not possible, because when the HttpSessionBindingEvent is
received, all attributes are already removed from the session and are
not accesible any more :(

To me dumping session variables on expiration seems to be a pretty
normal usecase, I can't believe there is no easy way of doing that.

A quick perusal of the javadocs (always a good place to start) shows
methods getName() and getValue() in HttpSessionBindingEvent. Have you
tried it?
 
A

Andrea Desole

Hi Andrea,



attributes ...
This is not possible, because when the HttpSessionBindingEvent is
received, all attributes are already removed from the session and are
not accesible any more :(

You might actually be right, even if it's quite counterintuitive. I
would say that an event is fired after an object is removed, not after
all the objects have been removed. Even worse, I can't find anything in
the specs about that. Servlet lifecycle is not very well defined, I think.
Actually, after looking at the documentation, I would even say that
apparently sessionDestroyed is called before valueUnbound or
attributeRemoved (this is also, of course, not clear at all). This means
that probably you can't remove your sessions from the set (or the
container you are using) in the sessionDestroyed. Your container will
grow. If it's true, I would consider Sudsy's solution, since it implies
only one object. In the valueUnbound for that object you can remove the
session from the set. This is probably safer and more portable.
To me dumping session variables on expiration seems to be a pretty
normal usecase, I can't believe there is no easy way of doing that.
Chris

The way I look at it, I would be glad at least to have a good
understanding of how this thing works. I looked at the servlet 2.3
specs, and I don't expect newer versions to be much better.
 
S

Silvio Bierman

It is simple and obvious.

You must create a single object that holds the session status including ALL
your variables. It might even contain methods.

Something like this:

class SessionObject implements HttpSessionBindingListener
{
//all session state represented in private members
public void doGet(HttpServletRequest req,,HttpServletResponse resp)
{
//handle get-response for this session
}
public void doPost(HttpServletRequest req,,HttpServletResponse resp)
{
//handle post-response for this session
}
public void valueBound(HttpSessionbindingEvent event)
{
//handle session-initialization
}
public void valueUnbound(HttpSessionbindingEvent event)
{
//handle session-cleanup
}
}

Program your sessions through this class or something based on the same
idea. In your servlet create the sessions as you already do, populating each
session with EXACTLY ONE session object if it is a new session. For each
existting session (and also for the newly created ones) use the session
object to delegate the get/post messages to.

Simple, clean and as efficient as it gets. Putting application properties in
a session is not smart, simply put a session facade object in.

Hope this helps,

Silvio Bierman
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,045
Latest member
DRCM

Latest Threads

Top