2

我是 JSF 新手,我正在处理 JSF 应用程序的会话超时。我正在尝试使代码适用于 ajax 调用,但到目前为止无法实现。我尝试了两种方法:

方法 1:SessionListener(用于清理工作)和 SessionFilter(用于过滤每个请求并检查会话是否超时)我的过滤器代码片段:

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

方法二:CustomeExceptionHandler 处理 ViewExpiredException 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();  
}

这两种方法都适用于非 ajax POST 调用,但不适用于 ajax 调用。当我在调试模式下运行我的应用程序时,我还可以单步执行 ajax 调用的所有语句,这让我知道控件确实来到了我的代码中,执行了它,但由于某种原因,UI 上没有任何反应。我一直在尝试将用户重定向到超时页面,但理想的做法是显示一个 JSF 对话框并在点击“确定”后将用户带到主屏幕(我的应用程序没有登录屏幕。)我也有一个基本问题,视图到期与会话超时完全相同吗?

任何帮助将不胜感激,谢谢,斯瓦蒂。

4

0 回答 0