Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Session Timeout AJAX Error in Tapestry Application

I'm building a webapp using Tapestry in combination with Spring Security and the jQuery-library besides Prototype. When a user clicks on a link after his session timed out, he is automatically redirected to the login page. This, of course, does not work for links, that trigger an AJAX-request.

I know, this is a common problem with any kind of web application (e.g. http://www.openjs.com/articles/ajax/session_timeout.php). Is there a best practice solution for Tapestry 5?

EDIT The following solution (thanks to Henning) works for me:

Ajax.Responders.register(
{
    onException: function()
    {
        window.location.reload();
    }
});

In case of a failure during an AJAX-call a page reload is triggered, which in result redirects to the login-page. It still needs some tuning (e.g. display an error message instead of redirect), but using Ajax.Responders basically seems a good way to do it.

like image 203
martin Avatar asked Sep 17 '10 07:09

martin


2 Answers

For the AJAX that uses Prototype, you could add a global listener that reacts to AJAX failures using AJAX.Responders; jQuery has a similar construct called Ajax Events that you could use.

Both event handlers should just redirect to the login page on a 403 error. You could create a mixin with this functionality and add it to your layout component.

I have also used a mechanism that prevents session timeouts while the app is still open in a browser window by just doing an AJAX call and receiving an empty response every couple of minutes, thus keeping the session open. Stupid, but works okay.

like image 72
Henning Avatar answered Oct 05 '22 03:10

Henning


you can contribute the T5 master dispatcher


public class AjaxAccessController implements Dispatcher {

    @Override
    public boolean dispatch(Request request, Response response) throws IOException {

        // Si no hay session y la petición es ajax, recargar la página
        Session session = request.getSession(false);
        if (session == null && request.isXHR()) {
            OutputStream os = response.getOutputStream("application/json;charset=UTF-8");
            os.write("{\"script\":\"window.location.reload();\"}".getBytes());
            os.flush();
            return true;
        }

        return false;
    }
}

In your AppModule.java


public static void bind(ServiceBinder binder) {
        // binder.bind(MyServiceInterface.class, MyServiceImpl.class);
        // Make bind() calls on the binder object to define most IoC services.
        // Use service builder methods (example below) when the implementation
        // is provided inline, or requires more initialization than simply
        // invoking the constructor.

        // Id de AjaxAccessController
        binder.bind(AjaxAccessController.class).withId("AjaxAccessController");
    }

public void contributeMasterDispatcher(
            OrderedConfiguration configuration,
            @InjectService("AjaxAccessController") Dispatcher accessController) {

        configuration.add("AjaxAccessController", accessController, "before:ComponentEvent");
    }

So every ajax request without session, the page will reloads and it redirects to your index page

like image 22
iberck Avatar answered Oct 05 '22 02:10

iberck