Java Notes From My Desktop

Tags - Categories : All | Articles | Book Reviews | CSS | Java | Javaranch | Javascript | News | Opengl | Opinions | Personal | php

I doubt what I am about to write is new. In fact, I drudged up bits and pieces all over the internet from searches and kind of combined a few approaches into my own. So if you are reading this and you say to yourself "Hey, I came up with that" then I thank you. But hopefully someone can gain from this anyway.

One of the few things I despise about AJAX is handling session timeouts. Nothing about it is very graceful and my solution doesn't improve on that. However, it is simple and easy. Basically, the problem is that when a web applications session times out we typically want to redirect the user to the login page. I do this in Stripes using an Interceptor but you can think of that as a Filter or what have you. Basically, something on the server side is checking to see if the session has timed out and redirecting the request appropriately. Something kind of like this

if ( user == null && servletPath.startsWith("/admin"))
{
    executionContext.getActionBeanContext().getMessages().add( new LocalizableMessage( "/AdminLogin.action.notLoggedIn" ) );
    return new ForwardResolution( AdminLoginActionBean.class );
}

if ( user == null && servletPath.startsWith("/advisor"))
{
    executionContext.getActionBeanContext().getMessages().add( new LocalizableMessage( "/AdvisorLogin.action.notLoggedIn" ) );
    return new ForwardResolution( AdvisorLoginActionBean.class );
}

In order to get AJAX requests to change the browser location you have to rely on JavaScript, sad to say. What I do is I add 'ajax=' as a parameter to all my AJAX requests. In my Interceptor/Filter I look for this parameter. If I find it and the session has timed out, I change the HttpServletResponse.status to 403

if (map.containsKey("ajax"))
{
	ajax = true;
	if (session.isNew())
	{
		logger.debug("###########: SESSION IS NEW");
                executionContext.getActionBeanContext().getResponse().setStatus(403);
		return executionContext.proceed();
	}
}

Using Prototype I set an on403 for all my AJAX requests and call a simple function called sessionTimeout() which does this:

window.location = window.location

What that does is refreshes the page so that the first bit of code I showed above takes over and you actually get to the correct login page.

The only problem with this approach is that if you are doing Ajax.Updater you'll get the login page in whatever DIV element you've specified before the page redirects from the sessionTimeout function. Aside from that it works great.


Gregg, This is actually very good stuff, I was not sure how to deal with this. Yes it isn't pretty but it works fine. Our filter builds an encoded targetUrl param by looping over the parameter map. (similar to the bugzooky example) but when they login again the request params are restored like nothing happened. I no longer use Ajax.Updater but use these wrapper functions var KEY_LET_AJAX_PASS_THROUGH = "letAjaxPassThrough"; function ajaxUpdater(requestUrl, request, container) { existingOnSuccess = request.onSuccess; request.onSuccess = function transport(response) { $(container).innerHTML = response.responseText; if (existingOnSuccess != null) { existingOnSuccess(response); } }; ajaxRequest(requestUrl, request); } function ajaxRequest(requestUrl, request) { request.postBody = request.postBody + '&' + KEY_LET_AJAX_PASS_THROUGH + '='; existingOn403 = request.on403; request.on403 = function transport(response) { window.location = window.location; if (existingOn403 != null) { existingOn403(response); } }; new Ajax.Request(requestUrl, request); } works great! We finally handle session timeouts correctly, always redirect to login page, and after login proceed back where they wanted to go like nothing happened.


Add a comment

Title
Body
HTML : b, i, blockquote, br, p, pre, a href="", ul, ol, li
Math Quiz 2 + 8 = (Helps stop blog spam)
Name
E-mail address
Website
Remember me Yes  No 

E-mail addresses are not publicly displayed, so please only leave your e-mail address if you would like to be notified when new comments are added to this blog entry (you can opt-out later).

TrackBack to http://radio.javaranch.com/gthought/addTrackBack.action?entry=1184876772552