4

有没有办法在不向客户端发送状态的情况下保持页面会话处于活动状态?我无法将 设置STATE_SAVING_METHODclient,我不想使用a4j:keepalive.

我尝试使用一个简单的隐藏 iframe 提交给有问题的 Bean,但它使主页无效。

我正在使用 JSF 1.2 和 myfaces。

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

4

2 回答 2

13

将 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>

根据服务器端配置(通过in${pageContext.session.maxInactiveInterval}可控的方式)打印会话尚未存在的剩余秒数,并减去 10 秒,只是为了在它自动过期之前准时,并转换为毫秒,所以它符合预期。<session-timeout>web.xmlsetInterval()

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

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

应该是这样的。

于 2012-01-09T19:54:33.687 回答
5

BalusC 的回答帮助我在我的应用程序中满足了这一要求,但由于我使用的是 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 分钟强制会话超时(通过基于 web.xml 中 session.maxInactiveInterval 和会话超时值的元刷新重定向到 sessionExpired.xhtml);如果用户在一个页面上执行一堆 AJAX 请求,则会话将超时,因为 AJAX != 整页刷新,但此代码允许最终用户在最终用户在应用程序的工资单页面上时“保持会话活动”,并且会话保持活动状态1到2个小时!:)

于 2013-10-21T06:49:56.263 回答