2

I am new to JSF and I am working on handling session timeout for a JSF application. I am trying to get the code to work for ajax calls and not able to achieve that so far. I have tried two approaches:

Approach 1: SessionListener (for cleanup work) and SessionFilter (for filtering every request and checking if session timed out) My Code snippet for Filter:

if ((request instanceof HttpServletRequest)  
            && (response instanceof HttpServletResponse)) {  
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;  
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;  

        // is session expire control required for this request? (not required for home page or timeout page or JSF resources)  
        if (isSessionControlRequired(httpServletRequest)) {  

            // is session invalid?  
            if (isSessionInvalid(httpServletRequest)) {  
                String timeoutUrl = httpServletRequest.getContextPath() + "/timeout.html";  
                logger.info("session is invalid! redirecting to timeoutpage : " + timeoutUrl);  
                //httpServletResponse.sendRedirect(timeoutUrl);  
                //final FacesContext facesContext = FacesContext.getCurrentInstance();  
                //final ExternalContext externalContext = facesContext.getExternalContext();  
                //externalContext.dispatch("/start.jsp");  
                RequestDispatcher rd = httpServletRequest.getRequestDispatcher("/timeout.html");  
                rd.forward(httpServletRequest, httpServletResponse);  
                return;  
            }  
        }  
    }  
    chain.doFilter(request, response);  

Approach 2: CustomeExceptionHandler handling ViewExpiredException Code snippet of handle() :

for (final Iterator<ExceptionQueuedEvent> it = getUnhandledExceptionQueuedEvents().iterator(); it.hasNext();) {  
        Throwable t = it.next().getContext().getException();  
        while ((t instanceof FacesException || t instanceof ELException) && null != t.getCause()) {  
            t = t.getCause();  
        }  
        if (t instanceof ViewExpiredException) {  
            final FacesContext facesContext = FacesContext.getCurrentInstance();  
            final ExternalContext externalContext = facesContext.getExternalContext();  
            final Map<String, Object> requestMap = externalContext.getRequestMap();  
            NavigationHandler nh = facesContext.getApplication().getNavigationHandler();  
            try {  
                final String viewId = ((ViewExpiredException) t).getViewId();  
                String message = "View has expired. " + viewId;  
                logger.error(message);  
                requestMap.put("errorMsg", message);  
                try {  
                    requestMap.put("currentViewId", viewId);  
                    nh.handleNavigation(facesContext, null, "/timeout.html");  
                    facesContext.renderResponse();  

                    // Force JSF to render the error page in its entirety to the ajax response.  
                    //facesContext.setViewRoot(facesContext.getApplication().getViewHandler().createView(facesContext, "/timeout.html"));  
                    //facesContext.getPartialViewContext().setRenderAll(true);  
                    //facesContext.renderResponse();  

                    //RequestContext rc = RequestContext.getCurrentInstance();  
                    //rc.execute("addTitleDialog.show()");  

                    //externalContext.dispatch("/start.jsp");  
                }  
                catch (final Exception e) {  
                    logger.error("Cannot dispatch to /start.jsp");  
                }  
                facesContext.responseComplete();  
            }  
            finally {  
                it.remove();  
            }  
        }  
        else {  
            logger.error(t.getMessage(), t);  
        }  
    }  
    getWrapped().handle();  
}

Both these approaches work for non-ajax POST calls but not for ajax calls. When I run my app in debug mode, I can step through all the statements for ajax calls also, which gives me an idea that the control does come to my code, executes it but for some reason, nothing happens on the UI. I have been trying to redirect user to a timeout page but the ideal thing would be to display a JSF dialog and upon hitting 'OK' take user to Home Screen (My app does not have a login screen.) I have a basic questions also, is view expiring exactly same as session timeout?

Any help would be much appreciated, thanks, Swati.

Swati
  • 27
  • 1
  • 8
  • Your issue seems already answered by BalusC: [Session timeout and ViewExpiredException handling on JSF/PrimeFaces ajax request](http://stackoverflow.com/questions/11203195/session-timeout-and-viewexpiredexception-handling-on-jsf-primefaces-ajax-request) – Nicolas Labrot Feb 19 '13 at 14:05
  • Thanks for responding Nicolas. Well, I went through the post and tried what was suggested but it did not work for me. The commented lines in the code snippet I posted, I have tried them but did not work for some reason. I had one question about it though, the errorPageLocation is /WEB-INF/errorpages/expired.xhtml. Should WEB-INF be there? Anyway I tried various combinations there. – Swati Feb 19 '13 at 15:14
  • I used omniFaces the way BalusC showed.. it works perfect.. just that I would prefer displaying the timeout message in a dialog instead of another facelet. Still, I am grateful to get the pressure off my back, now trying to tweak the code to display the dialog. – Swati Feb 19 '13 at 20:36

0 Answers0