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.
I know this is an old post but not much information out there about it...
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.
If you examine the request header you can determine what type of request it is, i.e AJAX or Otherwise... in PHP this is:
isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest'
If AJAX then respond with a header 403 only in which case not content is sent back to render and the on403 handler can do what it does without having the contents of the login page rendered into the div, works for Ajax.Updater as well.
This is a good example. Its easy to learn something about it.. Thanks a lot..!
Great post. A thought, depending upon application you could implement a login popup box which performs login via an AJAX request and then automatically resubmit the 403'ed AJAX request.
I stumbled across your post today while trying to find out how to solve the AJAX session issue. The project I'm working on uses PHP, Zend Framework and jQuery and I've set it up as follows:
  • In my PHP Controller when I detect an expired session I send a HTTP response code of 401
  • jQuery's $.ajax({}) has a super awesome statusCode method that can be called when a certain HTTP response code is encountered. Using the $.ajaxSetup({}) to set a global default of:
  • $.ajaxSetup({
      statusCode: {
        401: function() {
    	// Anything you like here, even window.location.href = "/errors/sessionexpired/"
    	alert('Your session has expired');
        }  
      }
    });
    

Now whenever I get a 401 response I redirect the user to a page explaining that they need to login again.

What's really nice about this method is that it required very few changes. Once in the controller to set the HTTP response code and then a few lines of JavaScript to setup the defaults which all future AJAX requests would make use of.

Nice classic short boots with the able adroitness and abundant affection are account of your purchasing. These ugg boots sale are able-bodied fabricated with the artistic design. With the heel bouncer apparent with a characterization, these ugg boots do attending actual timeless. The shoelaces are advanced and the eyelets are big. Thus, these Kids Ugg Boots attending altered from the accustomed winter boots in the appearance market. Featuring the lining abounding with sheepskin, the ugg boots can wick damp abroad for your feet. You can get pleasure the absolute warmth, abundance and benevolence of these absolute thigh-high style boots. It adds abundant absorption to the Appearance Sheepskin ugg boots. http://www.uggbootssale-au.net/
thanks for sharing.
OLYMPIA è pratico ed elegante, perché è la forma del corpo di progettazione ai sensi e opere classiche. CITYRUSH è realizzata con materiali impermeabili, così la gente può indossare qualunque cosa che sia. Contorno pulito e ordinato e il design semplice e moderno può aiutare le persone a mettere in evidenza la loro immagine esperto e maturo. Ciò di cui abbiamo accennato sopra è solo la punta dell'iceberg di vantaggi di Hogan. In una parola, Hogan fa funzionare, estetica, lusso e divertimento per uno.
Lo sapevi esattamente che cosa una pagina di domanda può essere? Se lo fai, ti capita di essere di una razza eccezionale, una copia scrittore. La maggior parte delle persone mai. Mi sono imbattuto su questa specifica, mentre ho fatto "Letters Domanda immediata" pacchetto software. "Che c'è una nuova pagina queer? Pollici che informarsi.


Add a comment

Title
Body
HTML : b, i, blockquote, br, p, pre, a href="", ul, ol, li
Math Quiz 2 + 9 = (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