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

问题描述 投票:4回答:2

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

我已经尝试使用提交给Bean的简单隐藏iframe,但它使主页无效。

我正在使用JSF 1.2和myfaces。

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

jsf viewexpiredexception
2个回答
11
投票

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

<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()在给定的URL上发送ajax GET请求。对于上面的示例,您需要在/poll的URL模式上映射servlet,并在doGet()方法中基本执行以下操作:

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

那应该是它。


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个小时! :)

© www.soinside.com 2019 - 2024. All rights reserved.