Session 检查会话是否存在JSF

Session 检查会话是否存在JSF,session,jsf,jsf-2,viewexpiredexception,Session,Jsf,Jsf 2,Viewexpiredexception,我有一个登录页面,其中有一个用户bean来验证一个人的用户名和密码。这个Bean是会话范围的。 如果有人写入URL并试图跳转登录页面,我如何检查并将其重定向到登录页面 另一方面。假设我已经登录并且正在工作,突然我出去了一段时间,我的会话过期了。当我返回并尝试与表单交互时,它会发送一条消息,提醒我会话过期。发生这种情况时,我如何再次重定向到登录表单 提前谢谢。希望我能解释清楚 Mojarra 2.1.4,Tomcat 7,Tomahawk 1.1.11 如果有人写入URL并试图跳转登录页面,我如何

我有一个登录页面,其中有一个用户bean来验证一个人的用户名和密码。这个Bean是会话范围的。 如果有人写入URL并试图跳转登录页面,我如何检查并将其重定向到登录页面

另一方面。假设我已经登录并且正在工作,突然我出去了一段时间,我的会话过期了。当我返回并尝试与表单交互时,它会发送一条消息,提醒我会话过期。发生这种情况时,我如何再次重定向到登录表单

提前谢谢。希望我能解释清楚

Mojarra 2.1.4,Tomcat 7,Tomahawk 1.1.11

如果有人写入URL并试图跳转登录页面,我如何检查并将其重定向到登录页面

您似乎正在使用自制的身份验证。在这种情况下,您需要实现一个。JSF将会话范围的托管bean存储为
HttpSession
的属性,因此您可以在
doFilter()方法中检查该属性:

HttpServletRequest req = (HttpServletRequest) request;
UserManager userManager = (UserManager) req.getSession().getAttribute("userManager");

if (userManager != null && userManager.isLoggedIn()) {
    chain.doFilter(request, response);
} else {
    HttpServletResponse res = (HttpServletResponse) response;
    res.sendRedirect(req.getContextPath() + "/login.xhtml");
}
在覆盖安全页面的URL模式上映射此筛选器,例如
/app/*


当我返回并尝试与表单交互时,它会发送一条消息,提醒我会话过期。发生这种情况时,如何再次重定向到登录表单

我知道这与Ajax请求有关?对于普通请求,您可以在
web.xml
中使用
。如果在
web.xml
中将状态保存方法设置为client,如下所示

<context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>client</param-value>
</context-param>
(请注意,此特定示例导航到
viewexpired
,因此它需要一个
/viewexpired.xhtml
作为错误页面)

以上内容需要通过以下实现进行烘焙:

public class ViewExpiredExceptionHandlerFactory extends ExceptionHandlerFactory {

    private ExceptionHandlerFactory parent;

    public ViewExpiredExceptionHandlerFactory(ExceptionHandlerFactory parent) {
        this.parent = parent;
    }

    @Override
    public ExceptionHandler getExceptionHandler() {
        return new ViewExpiredExceptionHandler(parent.getExceptionHandler());
    }

}
这反过来需要在
faces config.xml
中注册,如下所示:

<factory>
    <exception-handler-factory>com.example.ViewExpiredExceptionHandlerFactory</exception-handler-factory>
</factory>

com.example.ViewExpiredExceptionHandlerFactory

如果您正在实现自己的系统,您可以向名为session或其他的用户添加一个属性。此属性可以是布尔值,因此每当会话启动时,都可以将此属性设置为true。编写一个名为权限的方法,例如:

public void permission() throws IOException {

        if(userStatelessBean.getSession() == false) {
            System.out.println("*** The user has no permission to visit this page. *** ");
            ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
            context.redirect("login.xhtml");
        } else {
            System.out.println("*** The session is still active. User is logged in. *** ");
        }
    }
在您想要限制的每个jsf页面(本例中)上,您可以在页面的最开始添加以下代码:

<f:metadata>
     <f:event type="preRenderView" listener="#{sesija.permission()}"/>
</f:metadata>

这将要做的是在呈现页面之前调用对象名为sesija的JSF ManagedBean,并检查您在指定方法中创建的rules是否满足要求

我希望你觉得这很有用


谢谢。

对此我有点怀疑。我被要求添加一个commandLink,上面写着“转到主页面”,但当我点击它时,它会首先转到ViewExpired页面,然后我必须再次点击才能转到主页面。如何在不点击commandLink的情况下直接进入主页面?将其设置为正常的
,它发送一个新的GET请求,而不需要查看状态。你不需要通过邮寄提交任何数据,对吗?这解决了问题,但出现了另一个问题。如果我仍在登录页面中,ViewExpiredException也会发生。如何避免这种情况?显然,该页面是从浏览器缓存而不是服务器提供的。您需要告诉浏览器不要缓存这些页面。您可以使用过滤器执行此操作,另请参见“确定”。读一下。所以我必须把这个过滤器放在UserBean中,或者放在哪里?它是一个单独的类吗?U.V.因为这有助于我管理权限,但这并没有回答真正的问题(管理过期视图)
<f:metadata>
     <f:event type="preRenderView" listener="#{sesija.permission()}"/>
</f:metadata>