让会话无限期地保持活跃状态

时间:2012-01-09 18:07:16

标签: jsf viewexpiredexception

有没有办法让页面的会话保持活动而不需要将状态发送到客户端?我无法将STATE_SAVING_METHOD设置为client,我宁愿不使用a4j:keepalive

我尝试过使用提交给相关Bean的简单隐藏iframe,但它会使主页无效。

我正在使用JSF 1.2和myfaces。

这是为了在不需要用户登录的页面上绕过ViewExpiredException。大多数现有站点都要求用户登录。

2 个答案:

答案 0 :(得分:12)

将ajax轮询实施为“心跳”以使会话保持活动状态。最简单的是,您可以通过一点jQuery来实现此目的,以避免200行的样板代码使其在世界上所知的所有不同浏览器中工作:

<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
    $(document).ready(function() {
        setInterval(function() {
            $.get("${pageContext.request.contextPath}/poll");
        }, ${(pageContext.session.maxInactiveInterval - 10) * 1000});
    });
</script>

${pageContext.session.maxInactiveInterval}根据服务器端配置(可由<session-timeout>中的web.xml控制的方式)打印会话尚未生存的剩余秒数,并扣除10秒,只是在它自动到期之前准时,并转换为毫秒,以使其适合setInterval()期望的值。

$.get()在给定的网址上发送ajax GET请求。对于上面的示例,您需要在/poll的URL模式上映射servlet,并在doGet()方法中基本执行以下操作:

request.getSession(); // Keep session alive.

应该是它。

答案 1 :(得分:5)

BalusC's answer帮助我在我的应用程序中满足了这个要求,但由于我使用的是PrimeFaces,我想分享一下BalusC的答案如何启发我用来执行此操作的代码。

xhtml页面

<p:poll listener="#{pf_usersController.keepUserSessionAlive()}"
        interval="#{session.maxInactiveInterval - 10}" />

public void keepUserSessionAlive() {
    FacesContext context = FacesContext.getCurrentInstance();
    HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
    request.getSession();
}

一如既往,谢谢你,BalusC!

编辑:最终用户今天早上对此进行了测试,效果很好!我的应用程序通常在整页刷新后15分钟强制会话超时(通过基于session.maxInactiveInterval和web.xml中的会话超时值的元刷新重定向到sessionExpired.xhtml);如果用户在一个页面上执行一堆AJAX请求,会话将超时,因为AJAX!=整页刷新,但此代码允许最终用户“保持会话活动”,而最终用户在应用程序的工资单页面上,并且会话保持活动状态1到2个小时! :)