【问题标题】:Keep a session alive for an indefinite amount of time使会话无限期保持活动状态
【发布时间】:2012-02-06 06:17:14
【问题描述】:

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

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

我正在使用 JSF 1.2 和 myfaces。

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

【问题讨论】:

  • 你能解释一下用例吗?
  • @AdrianMitev 当然,我添加了一些额外的 cmets。 ViewExpiredException 在大约 10 分钟后触发。我无法更改超时时间。

标签: jsf viewexpiredexception


【解决方案1】:

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

【讨论】:

  • 我不推荐这个技巧。如果您在对话中,则可能会收到 javax.enterprise.context.BusyConversationException。例如,用户单击一个按钮。同时轮询器唤醒,但鉴于对话请求是序列化的,如果前一个请求花费超过一秒,轮询器请求可能会超时(BusyConversationException)。问题是轮询请求不应该存在于对话中。 BalusC 解决方案完全避免了这个问题。
  • @agori,谢谢。在我的例子中,pf_usersController 是 CDI SessionScoped,我不使用会话范围的 bean。
【解决方案2】:

实施 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} 根据服务器端配置(顺便说一下,web.xml 中的&lt;session-timeout&gt; 可以控制)打印会话尚未存活的剩余秒数,并减去 10 秒,只是为了在它自动过期之前准时,并转换为毫秒,以便它适合 setInterval() 的期望。

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

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

应该是这样的。

【讨论】:

  • 这个策略很棒,可以将 web.xml 中的 session-timeout 减少到低至 1 分钟,并保持高 session timeout 值的要求。在 web.xml 中增加 sessiont-timeout 的问题是,即使是未使用的 viewscoped 逻辑视图也会在给定的超时时间内存储,以防您直接 GET 导航(与 JSF 导航相反)。
猜你喜欢
  • 2019-08-24
  • 2012-04-10
  • 1970-01-01
  • 1970-01-01
  • 2018-11-26
  • 1970-01-01
  • 2020-09-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多