salut
je veut savoir s'il existe une maniere pour exclure mon login page de session-timeout.
en effet ,mon session-timeout =30 et si mon login page depasse cette durée,j'obtient une erreur 500
Version imprimable
salut
je veut savoir s'il existe une maniere pour exclure mon login page de session-timeout.
en effet ,mon session-timeout =30 et si mon login page depasse cette durée,j'obtient une erreur 500
ouii tu peux envoyer périodiquement (29min et 58s),une requête ajax, dans la page de login, à l'aide de a4j:poll par exemple.
Ca devrait marcher (bon, personnellement, je mettrais cet intervalle un peu plus faible, genre 28m, on ne sait jamais).
j'ai testé et ça à l'air de marcher sauf pour un cas particulier:
si par example une autre page(non login page) reste inactif pendant la periode de session-timeout, cette page sera rediriger vers mon login page et si j'entre mon login et password j'aurai le meme probleme:authentification non faite à cause de l'erreur:
qu'est ce que je doit faire?Code:
1
2 javax.faces.application.ViewExpiredException: viewId:/pages/userLogin.jsf - View /pages/userLogin.jsf could not be restored.
a partir du moment ou tu a redirigé vers la page de login suite à un timeout, tu devrais avoir une session toute neuve! Comment tu fait cette redirection vers le login?
j'ai utilisé un filtre et en voici le code:
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 public class TimeoutFilter implements Filter { private static final String LOGIN_PAGE = "pages/userLogin.jsf"; public void init(FilterConfig filterConfig) throws ServletException { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { if ((request instanceof HttpServletRequest) && (response instanceof HttpServletResponse)) { HttpServletRequest hRequest = (HttpServletRequest) request; HttpServletResponse hResponse = (HttpServletResponse) response; System.out.println("etatchek=="+checkResource(hRequest)); if (checkResource(hRequest)) { System.out.println("erreur appelation"); if(hRequest.getSession().getAttribute("User")==null) { String timeoutUrl = hRequest.getContextPath() + "/" + LOGIN_PAGE; hResponse.sendRedirect(timeoutUrl); } else if (checkSession(hRequest)) { String timeoutUrl = hRequest.getContextPath() + "/" + LOGIN_PAGE; hResponse.sendRedirect(timeoutUrl); return; } } } filterChain.doFilter(request, response); } private boolean checkResource(HttpServletRequest request) { String requestPath = request.getRequestURI(); HttpServletRequest hRequest = (HttpServletRequest) request; return !(requestPath.contains(LOGIN_PAGE) || requestPath.equals(hRequest.getContextPath() + "/")); } private boolean checkSession(HttpServletRequest request) { return request.getRequestedSessionId() != null && !request.isRequestedSessionIdValid(); } public void destroy() { } }
remplace
parCode:sendRedirect(timeoutUrl)
ca permettra d'envoyer au login le nouveau numéro de session.Code:sendRedirect(response.encodeURL(timeoutUrl))
et en utilisant;
Code:
1
2
3
4
5
6
7
8
9
10 String pageURI = "..." ; FacesContext facesContext = .. ; ExternalContext externalContext = facesContext.getExternalContext(); try { externalContext .redirect(pageURI); } catch (IOException e) { // TODO Auto-generated catch block }
j'ai ajouté ce code:
j'ai obtenu alors un nullpointerexception causé par la ligne:Code:
1
2
3
4
5
6
7
8
9 FacesContext facesContext = FacesContext.getCurrentInstance(); ; ExternalContext externalContext = facesContext.getExternalContext(); try { externalContext .redirect(LOGIN_PAGE); } catch (IOException e) { e.printStackTrace(); }
Code:ExternalContext externalContext = facesContext.getExternalContext();
initialise le FacesContext, le code c'est à titre explicatif pas pour le copier/coller.
va faire exactement la meme chose que ton code, donc ca sert à rien. De plus "initialiser" le FacesContext est loin d'être une mince affaire. Donc évite. Essaie, avant le redirect et en faisant bien un encoreURL, de faire un session.invalidate(); Fait bien le invalidate *avant* le encodeURL!Code:externalContext .redirect(LOGIN_PAGE);
j'ai ajouté invalidate session comme suit:
mais toujours même resultat:Code:
1
2 hRequest.getSession().invalidate(); hResponse.sendRedirect(hResponse.encodeURL(timeoutUrl));
Code:javax.faces.application.ViewExpiredException: viewId:/pages/userLogin.jsf - View /pages/userLogin.jsf could not be restored.
Ok, je viens de tilter :s
Si ma mémoire est bonne, dans le redirect, les règles HTTP disent que le borwser doit resoumettre ses donnée (POST/GET) à la nouvelle adresse -> ton navigateur soumet un nouvelle demande pour login.jsf (suivant le redirect) en faisant un POST avec un viewId qui ne correspond plus à rien puisque session out.
Il serait probablement plus simple de remplacer ton redirect par ceci
surcharge de HttpServletRequestWrapper
surcharge des méthode getParameterXXX pour qu'elles renvoient "du vide"
appel au requestDispatcher.forward pour faire effectuer le rendu par login.jsf
De cette manière
- plus de paramètre (get/post) disponble --> jsf va faire un createView
- par de redirect nécessaire
Exacte!!
mais il est obligé d'avoir le facecontext pour sauvegarder le viewRoot afin qu'il soit disponible dans le GET de la redirection.
Je pense que c'est peut être mieux d'utiliser le PhaseListener.
Le filtre est utilisé seulement pour détecter le session timeout? si ouii y'a d'autre solutions adéquates.
Pour le PhaseLisneter voici des exemples d'utilisation: un et deux.
Sinon pour l'expiration de session, si tu utilises Richfaces, y'a une fonction javascript A4J.ajax.onExpired lancé à l'expiration de session, tu peux l'utiliser pour faire une redirection: voici un exemple
Enfin,il existe un listner pour la session HttpSessionLisneter et voilà un exemple.
montre le code ?
qu'est ce qui ne fonctionne pas?
non, je veut dire que le probleme est toujours present:
lorsque je clique sur le bouton sessionEx je retrouve bien ma page de login mais l'acion de login ne se fait que lorsque je refraichit la page manuellement.(ViewRoot est vide)Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 <rich:modalPanel id="sessionExpiredPanel"> <f:facet name="header">Session expired</f:facet> <rich:panel style="border:0;text-align:center;"> <h:form><h:commandLink value ="sessionEx" action="#{userLogin.Deconnexion}" /></h:form> </rich:panel> </rich:modalPanel> <a4j:region> <a4j:form> <a4j:poll id="sessioncheck" interval="65000" reRender="sessioncheck" /> </a4j:form> <script type="text/javascript"> A4J.AJAX.onExpired = function(loc,expiredMsg){ Richfaces.showModalPanel('sessionExpiredPanel',{left:'auto',top:'auto'});} </script> </a4j:region>
donc à l'expiration de session, la modalPanel se lance, tu clique sur le button la redirection ne se fait pas?
montre le code de ton action.
le code de la méthode de déconnexion?
tu peux faire seulement:
Code:session.invalidate();
Non ça marche bien comme ça pour moi et juste en faisant:
Si la navigation se passe bien; il n'y a aucune raison pour que ça ne marche pas..Code:HttpSession session = (HttpSession) context.getExternalContext().getSession(true);
salut sniper,
je pense que j'ai trouvé une solution:j'ai trouvé qu'il vaut mieux est de revenir au mode compatibilité JSF 1.1 ;je ne sait pas pourquoi mais en ajoutant
dans web.xml le code suivant, je n'ai plus d'erreur:
Code:
1
2
3
4 <context-param> <param-name>com.sun.faces.enableRestoreView11Compatibility</param-name> <param-value>true</param-value> </context-param>
tu n'a pas ajouté ça:
Code:
1
2
3
4 <context-param> <param-name>org.ajax4jsf.handleViewExpiredOnClient</param-name> <param-value>true</param-value> </context-param>
Si tu utilises la solution Richfaces, vaut mieux l'utiliser..