2

我不会将我的用户重定向或转发到另一个页面。所以当 my SessionExpiredExceptionHandler(extends ExceptionHandlerWrapper) 处理 ViewExireException 时。我希望用户留在同一页面上并显示 PrimeFaces 对话框。用于通知会话已过期并且用户需要再次登录(基于对话框)。我使用 Servlet 3.1 功能来登录/注销用户,并Basic/file使用 auth-method 将用户映射到不同的系统角色。

现在发生的是视图/页面在 2 分钟后刷新,但会话没有失效。仅在 4 分钟后页面刷新时第二次发生。

    <session-config>
        <session-timeout>2</session-timeout>
    </session-config>

编辑: 由元标记刷新:

<meta http-equiv="refresh" content="#{session.maxInactiveInterval}" />

当异常第一次发生时,如何SessionExpiredExceptionHandler使会话对象(Servlet 注销)无效,以及如何在客户端调用 JavaScript(expireDlg.show())以显示 PrimeFaces 对话框?

我查看了其他一些线程,但没有找到可行的解决方案。 会话超时

SessionExpiredExceptionHandler

    @Override
    public void handle() throws FacesException {
    for (Iterator<ExceptionQueuedEvent> i = getUnhandledExceptionQueuedEvents().iterator(); i.hasNext();) {
        ExceptionQueuedEvent event = i.next();
        ExceptionQueuedEventContext context = (ExceptionQueuedEventContext) event.getSource();
        Throwable t = context.getException();
        if (t instanceof ViewExpiredException) {
        ViewExpiredException vee = (ViewExpiredException) t;
        FacesContext fc = FacesContext.getCurrentInstance();
        Map<String, Object> requestMap = fc.getExternalContext().getRequestMap();
        NavigationHandler nav = fc.getApplication().getNavigationHandler();                

        try {
            requestMap.put("currentViewId", vee.getViewId());

            nav.handleNavigation(fc, null, "Home");
            fc.renderResponse();

        } finally {
            i.remove();
        }                                
        }
    }
    // At this point, the queue will not contain any ViewExpiredEvents.
    // Therefore, let the parent handle them.
    getWrapped().handle();
    }

web.xml

<exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/home.xhtml</location>
</error-page>
4

2 回答 2

2

该解决方案适用于我的情况。Primefaces (3.3) 似乎正在吞噬 ExceptionQueuedEvent。当我的 ViewExceptionHandler 被调用时,没有要处理的异常。因此,我将p:idleMonitor组件与事件侦听器一起使用。我还删除了元刷新标签。

<p:idleMonitor timeout="#{(session.maxInactiveInterval-60)*1000}">
        <p:ajax event="idle" process="@this" update="sessionMsg" listener="#{userController.userIdleSession()}" />
        <p:ajax event="active" process="@this" update="sessionMsg" listener="#{userController.userActiveSession()}"/>
</p:idleMonitor>

一件奇怪的事情是,如果 与会话超时参数timeout完全相同web.xml,则不会调用侦听器。

豆函数

public void userIdleSession() {
    if (!userIdleMsgVisable) {
        userIdleMsgVisable = true;
        JsfUtil.addWarningMessage(JsfUtil.getResourceMessage("session_expire_title"), JsfUtil.getResourceMessage("session_expire_content"));            
    }
}

public void userActiveSession() {
        if (!userSessionDlgVisable) {
            userSessionDlgVisable = true;                     
            RequestContext.getCurrentInstance().execute("sessionExipreDlg.show()");            
        }
    }

对话框 ( sessionExipreDlg) 调用重定向而不是使用导航处理程序来获取新范围并刷新页面。

public void userInactiveRedirect() {
        FacesContext fc = FacesContext.getCurrentInstance();
        userIdleMsgVisable = false;
        userSessionDlgVisable = false;
        sessionUser = null;         
        HttpServletRequest request = (HttpServletRequest) fc.getExternalContext().getRequest();
        JsfUtil.findBean("homeController", HomeController.class).clearCurrentValues();        
        try {
            fc.getExternalContext().redirect(JsfUtil.getApplicationPath(request, false, null));            
        } catch (IOException ex) {
            BeanUtil.severe(ex.getLocalizedMessage());
        }
    }
于 2013-01-18T13:49:58.993 回答
2

第一次发生异常时,如何使 SessionExpiredExceptionHandler 使会话对象无效(Servlet 注销)

该会话应该已经失效/过期(否则ViewExpiredException根本不会抛出a ),所以我看不出自己手动使其失效/过期有什么用处。但是对于这种情况,您可以按如下方式使其无效:

externalContext.invalidateSession();

以及如何在客户端调用 JavaScript (expireDlg.show()) 来显示 PrimeFaces 对话框?

您可以使用 PrimeFaces RequestContextAPI 以编程方式指示 PrimeFaces 在完成 ajax 响应时执行一些 JS 代码。

RequestContext.getCurrentInstance().execute("expireDlg.show()");

如果您实际上不想导航,请不要忘记从异常处理程序中删除导航处理程序块。

于 2013-01-15T15:20:05.727 回答