2010-09-17 5 views
7

Je construis une webapp en utilisant Tapestry en combinaison avec Spring Security et la librairie jQuery en plus de Prototype. Lorsqu'un utilisateur clique sur un lien après l'expiration de sa session, il est automatiquement redirigé vers la page de connexion. Ceci, bien sûr, ne fonctionne pas pour les liens qui déclenchent une requête AJAX.Erreur de délai de session AJAX dans l'application Tapestry

Je sais, c'est un problème courant avec n'importe quel type d'application Web (par exemple http://www.openjs.com/articles/ajax/session_timeout.php). Existe-t-il une solution de meilleure pratique pour Tapestry 5?

EDIT La solution suivante (grâce à Henning) fonctionne pour moi:

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

En cas d'échec lors d'un AJAX appeler un rechargement de la page est déclenchée, ce qui fait réoriente la connexion -page. Il a encore besoin d'un réglage (par exemple, afficher un message d'erreur au lieu de rediriger), mais en utilisant Ajax.Responders semble fondamentalement un bon moyen de le faire. Pour l'AJAX qui utilise Prototype, vous pouvez ajouter un écouteur global qui réagit aux échecs AJAX en utilisant AJAX.Responders;

+0

faire ce que l'auteur suggère dans l'article. le rencontrer de javascript. – Adeel

+1

Juste recharger la page est une solution très élégante; Je vais en faire la nouvelle valeur par défaut pour mes applications. Merci! – Henning

Répondre

4

jQuery a une construction similaire appelée Ajax Events que vous pourriez utiliser.

Les deux gestionnaires d'événements doivent simplement rediriger vers la page de connexion sur une erreur 403. Vous pouvez créer un mixin avec cette fonctionnalité et l'ajouter à votre composant de présentation. J'ai également utilisé un mécanisme qui empêche les délais de session lorsque l'application est toujours ouverte dans une fenêtre de navigateur en effectuant un appel AJAX et en recevant une réponse vide toutes les deux minutes, maintenant ainsi la session ouverte. Stupide, mais ça va.

+0

Merci d'avoir signalé AJAX.Responders. Cela fonctionne bien! – martin

0

Eh bien, la requête Ajax est faite au serveur, il envoie l'en-tête "HTTP_X_REQUESTED_WITH" avec la valeur "XMLHttpRequest". Vous pouvez simplement vérifier sur le serveur que c'est une requête ajax avec l'en-tête et la condition ci-dessus pour le login et le timeout de la session avant d'aller plus loin dans votre page d'index.

Si vos critères sont identiques, imprimez simplement "window.top.location.href = 'page de connexion'" dans votre fonction.

En PHP, je peux le faire aussi,

<?php if($_SERVER['HTTP_X_REQUESTED_WITH'] === "XMLHttpRequest" && condition for session check){ 
    echo "<script>window.top.location.href='login.php'</script>"; 
    } 

?> 

Vous pouvez ajouter la condition similaire à dans votre cadre.

3

vous pouvez contribuer au répartiteur maître T5

 

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; 
    } 
} 
 

Dans votre 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"); 
    } 
 

Ainsi, chaque demande ajax sans séance, la page rechargements et redirige vers votre page d'index

+0

Cela n'a pas fonctionné pour moi sur Tapestry 5.3.7. Au lieu de cela j'ai utilisé un ComponentRequestFilter pour faire ce que vous avez fait dans le Dispatcher. –

Questions connexes