Servlet Session Management Question

  • Thread starter three-eight-hotel
  • Start date
T

three-eight-hotel

Hi all,

I'm trying to understand the context of sessions, within a Servlet a
little better...

If multiple browsers access a Servlet, essentially creating a session
for each browser, Does the Servlet have all of the information it
needs to be able to pick and choose across those sessions, for my
purposes of terminating a specific session?

Say, for example, the servlet takes a string identifier of
"my_session_id" as a parameter. Could I invoke a method on the
Servlet, from a remote service, passing the "my_session_id" identifier
for one of the browser's sessions and have the Servlet terminate the
session for the browser I passed the id for?

I'd be happy to provide more information, if it's needed, but I'm
basically trying to solve a problem with an in-house Portal we've
developed to make sure applications sessions are terminated
appropriately for applications participating in the Portal.

Any information would be greatly appreciated.

Thanks and best regards,
Todd
 
M

Manish Pandit

Hi all,
If multiple browsers access a Servlet, essentially creating a session
for each browser,

If you hit Ctl-N in IE to open a new window, you'll notice that the 2
browser windows share the same HTTP session. I am not sure if this
holds true in Firefox though.
Does the Servlet have all of the information it
needs to be able to pick and choose across those sessions, for my
purposes of terminating a specific session?

Yes. The servlet has a handle to the HttpServletRequest, which has a
getSession() method. Call it with 'false' to ensure you get the
session associated with this request. Read the javadoc to get an idea
of true vs. false in getSession(). Once you have the session, check
for null (again, read javadoc on why this is needed), and if non-null,
call invalidate( ) to invalidate the session.

-cheers,
Manish
 
T

three-eight-hotel

Thanks Manish,

But what if I want to grab a handle to a specific session and
terminate it, not from a browser initiation, but from another
application (i.e. my Portal)?

Scenario:
1. UserA logs into the Portal accesses Application1 (Portal does a
browser redirect, POSTing the application some useful information)
2. UserA naviagates back to the Portal and accesses Application2
3. UserB performs the same two steps above, meaning I now have two
users with browser initiated sessions in two separate applications.
4. Next... UserA initiates a Portal logout request (clicks on a
logout link)

As the Portal application, I would like to notify Application1 and
Application2 that UserA has logged out, so they can terminate UserA's
session in each of their applications respectively. As Application1
or Application2, how can I receive such a request (assuming for each,
I'm a Servlet), and terminate the specific session of interest?

In reading some of the Javadocs, I'm leaning towards the idea of using
a ServletListener in each of the applications and associating each
session object with an identifier that can be used to grab a specific
session and terminate it, on demand.

Does it sound like I'm on the right track? Is there a better way to
do this, or is this even possible? I'm not a seasoned Java developer,
but can fumble around ok... ;-)

Thank you so much for your response!

Best Regards,
Todd
 
M

Mike Baranczak

Sounds tricky.

As far as I know, outside of the context of a client request, there's no
way to get a handle to a session. I see three possibilities:

1. Read your servlet container docs to see if it allows multiple
applications to share sessions. If such a thing is possible, it'd save
you a lot of hassle.

2. Don't worry about terminating all the sessions right when a user logs
out. Just send a message to all your apps saying that "user X has logged
out". Each application will then maintain a list of all such messages,
and on every request will consult that list to see if the current user
has logged out elsewhere.

3. Don't store the login state in the session, but somewhere else which
is accessible to all the applications (like a database).

-MB
 
M

Manish Pandit

Thanks Manish,

But what if I want to grab a handle to a specific session and
terminate it, not from a browser initiation, but from another
application (i.e. my Portal)?

Scenario:
1. UserA logs into the Portal accesses Application1 (Portal does a
browser redirect, POSTing the application some useful information)
2. UserA naviagates back to the Portal and accesses Application2
3. UserB performs the same two steps above, meaning I now have two
users with browser initiated sessions in two separate applications.
4. Next... UserA initiates a Portal logout request (clicks on a
logout link)

As the Portal application, I would like to notify Application1 and
Application2 that UserA has logged out, so they can terminate UserA's
session in each of their applications respectively. As Application1
or Application2, how can I receive such a request (assuming for each,
I'm a Servlet), and terminate the specific session of interest?

In reading some of the Javadocs, I'm leaning towards the idea of using
a ServletListener in each of the applications and associating each
session object with an identifier that can be used to grab a specific
session and terminate it, on demand.

Does it sound like I'm on the right track? Is there a better way to
do this, or is this even possible? I'm not a seasoned Java developer,
but can fumble around ok... ;-)

Thank you so much for your response!

Best Regards,
Todd

Hi Todd,

I do not think it is possible to control sessions outside the context
of the "current" app. In your case, except for the sessions initiated
in the portal app, you do not really have a handle on any other
sessions that are initiated outside the portal. One solution could be
to embed links in your portal to show app-specific logout links. As
User1 launches App1, on his view, display an App1 logout link which
hyperlinks to App1's logout servlet or link. This will need all the
launched apps to have a logout link/servlet which you can invoke.

-cheers,
Manish
 
T

three-eight-hotel

Thanks Mike and Manish for your responses!

I'm still not sure how I'm going to go forward with this, but you have
both given me some good things to consider. The AJAX approach is
something worth considering, as I was originally trying to consider a
JavaScript solution, upon the logout action of a user.

I'm going to continue to mull this one over and will post back if I
come up with a solution.

Thanks again for the feedback, and best regards,
Todd
 
T

three-eight-hotel

As promised, I am sharing the solution we have come up with... Hope
it can help someone else trying to something similar, some day.

Best Regards - Todd

==================================================================================================
We decided to use the SessionListener as identified in another thread
I was reading.
When a user goes to an application from the Portal, that application
adds a key, passed by the Portal and the session to an active session
list. When the Portal sends the logout-POST to the application,
passing the the same key and some other useful data, the application
looks up the session in the active session list removes it and
invalidates the session.

Below are some classes/code we use. The code is not finished yet, but
is working as a prototype.


/**
* This class manages the pool of the websessionid's and their
corresponding sessions.
* This is used to have a handle on the session when the applications
logout gets called.
* The logout class gets the websession id from the request and uses
this
* collection to get the corresponding session. This parameter is then
used to invalidate that session.
* It is implemented as singleton and maintains a pool of session
objects.
*/
public final class SessionManager {

private static SessionManager instance = null;

/**
* Hashmap - for finding a session object (value) when the
websessionid (key) is known.
*/
private HashMap sessionPool=new HashMap();

/**
* Ensure singleton usage. Is called from getInstance(). Adds the
configured
* minimum number of connections to the pool.
* @see #getInstance()
*/
private SessionManager(){
if (ApplicationSettings.isInDebugMode()){
System.out.println(LogWriter.getFormattedTimeStamp()+"
SessionManager() initializing pool");
}
}

/**
* @return the SessionManager singleton instance
*/
public static synchronized SessionManager getInstance(){
if(instance == null) {
instance = new SessionManager();
}
return instance;
}

/**
* This method will try to return a session object from the pool.
If this is not possible
* within a certain time, it throws an exception.
* @param webSessionId the websessionid of the session.
* @return an HttpSession.
* @throws Exception if the timout is reached
*/
public HttpSession getSession(String webSessionId){
return (HttpSession)sessionPool.get(webSessionId);
}

/**
* This method will add a session object to the pool with the
corresponding websessionid.
* @param webSessionId the websessionid of the session.
* @param session the sessionobject corresponding to the
websessionid.
* @throws Exception if the timout is reached
*/
public void addSession(String webSessionId, HttpSession session)
{
sessionPool.put(webSessionId,session);
}

}

/////////////////////////////// from the login
code ////////////////////////////////////////
//first time login - add the session to the pool
String webSessionId = getPortalSessionIDFromSession(request);
SessionManager sessionManager =
SessionManager.getInstance();
if(webSessionId != null){
sessionManager.addSession(webSessionId,session);
if (ApplicationSettings.isInDebugMode()){
System.out.println(LogWriter.getFormattedTimeStamp()+"
Application's Session for webSessionId " + webSessionId +" added to
the pool. - SessionId: "+session.getId());
}

/////////////////////////////// from the logout
code ////////////////////////////////////////
//invalidate the session corresponding to the
da_web_session_id
String webSessionId =
(String)request.getParameter(PORTAL_WEB_SESSION_ID);
SessionManager sessionManager = SessionManager.getInstance();
if (webSessionId!=null) {

HttpSession session=sessionManager.getSession(webSessionId);
if (session!=null) {
String SessionId=session.getId();
session.invalidate();
if (ApplicationSettings.isInDebugMode()){

System.out.println(LogWriter.getFormattedTimeStamp()+" Application's
Session for webSessionId " + webSessionId +" invalidated. - SessionId:
"+SessionId);
}
} else {
if (ApplicationSettings.isInDebugMode()){
System.out.println(LogWriter.getFormattedTimeStamp()
+" Application's Session for webSessionId " + webSessionId +" is
null");
}
}
} else {
if (ApplicationSettings.isInDebugMode()){
System.out.println(LogWriter.getFormattedTimeStamp()+"
webSessionId is null");
}
}
 

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

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top