好的,简单的问题。我有一个 JSF 应用程序,包含一个登录页面。问题是,如果用户加载登录页面,离开一段时间,然后尝试登录,会话就会过期并引发 ViewExpiredException。当发生这种情况时,我可以重定向回登录,但这不是很顺利。如何允许此流程在无需额外尝试的情况下正确登录?

有帮助吗?

解决方案

<强>更新

从Mojarra 2.1.19 / 2.2.0开始,您现在可以将<f:view>的transient属性设置为true:

<f:view transient="true">
     Your regular content
</f:view>

您可以在此处阅读 Balusc 博客:

http://balusc.blogspot.com.br/2013 /02/stateless-jsf.html

<强>原始

如果你正在使用Facelets,你可以创建自己的ViewHandler来处理这个问题:

public class LoginViewHandler extends FaceletViewHandler
{
    public LoginViewHandler( ViewHandler viewHandler )
    {
        super( viewHandler );
    }

    @Override
    public UIViewRoot restoreView( FacesContext ctx, String viewId )
    {
        UIViewRoot viewRoot = super.restoreView( ctx, viewId );

        if ( viewRoot == null && viewId.equals( "/login.xhtml" ) )
        {
            // Work around Facelet issue
            initialize( ctx );

            viewRoot = super.createView( ctx, viewId );
            ctx.setViewRoot( viewRoot );

            try
            {
                buildView( ctx, viewRoot );
            }
            catch ( IOException e )
            {
                log.log( Level.SEVERE, "Error building view", e ); 
            }
        }

        return viewRoot;
    }
}

更改<!> quot; /login.xhtml <!> quot;到您的登录页面。这将检查它是否可以恢复您的视图,如果它不能并且当前视图是您的登录页面,它将为您创建和构建视图。

在face-config.xml中设置如下:

<application>
    <!-- snip -->
    <view-handler>my.package.LoginViewHandler</view-handler>
</application>

如果您正在使用没有Facelets的JSF(即JSP),您可以尝试让类扩展ViewHandlerWrapper - 请注意,buildView()将不可用。希望它自己的createView()可以正确设置视图,但我不能100%肯定JSF / JSP。

其他提示

听起来你的登录页面在会话范围内,当它真的不需要时。请求范围应该适用于登录页面(因为,实际上在用户登录之前不应该有任何会话)。一旦用户登录,您可能会重置此问题,但Phill的想法非常好。

使用jsp,您可以禁用包含此指令<%@ page session="false" %>的页面的会话。 jsf必须有类似的内容。

几个稍微有点hacky的解决方案:

  • (非常hacky)使用 <meta http-equiv="refresh" content="5"/> 标签以每隔一段时间自动重新加载页面。
  • 使用 JavaScript 函数定期向服务器发送“ping”请求以保持会话活动。

我们用 冰面 在工作中,它会自动检测您的会话何时过期,并显示一个弹出窗口,提醒您这一事实。但有时由于某种原因,我们的登录页面仍然会出现问题。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top