4

我需要保持 JSF 2.2 CDI 对话不会过期。我尝试实现一种心跳机制,在该机制中,我使用 Ajax 单击一个“隐藏”按钮,该按钮又调用一个 servlet。但对话仍然到期。出于测试目的,我将超时设置为 10 秒,我的代码如下所示。

// The begin conversation method in my managed bean
public void beginConversation() {
      if (conversation.isTransient())
      {
          conversation.setTimeout(10000);
          conversation.begin();
      }
}

// JQuery document ready function
$(document).ready(function() {
setInterval(function(){$.get("/HeartbeatServlet");}, 5000);

});

// Heartbeat servlet
@WebServlet("/HeartbeatServlet")
public class HeartbeatServlet extends HttpServlet{

private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response)
{
    System.out.println("Heartbeat Received");
    request.getSession();
}
}

它每 5 秒打印一次“收到的心跳”文本。但对话仍然到期。

4

4 回答 4

1

我们遇到了同样的问题。在 servlet 请求中添加“cid”没有帮助。根据我们的经验,心跳 Servlet 不知道会话。它将保持当前会话继续进行,但对会话没有帮助。

我们的解决方案是添加一个 viewscoped managedbean,我们在其中注入 Conversation。在 UI 上,我们使用 PrimeFaces p:poll 定期调用 managebean 上的方法。

该方法只是打印日志语句。

@ManagedBean
@ViewScoped
public class ConversationListener implements Serializable {

...

/**
 * Inject Conversation instance if it is available.
 */
@Inject
private Conversation conversation;
@Inject
FacesBroker facesBroker;

...

/**
 * Method to refresh current conversation
 */
public void renewConversation() {

    if (conversation == null) {
        System.out.println("no conversation");
    } else {
        HttpServletRequest request = (HttpServletRequest) facesBroker.getContext().getExternalContext().getRequest();
        log.info("***     ConversationListener called for conversation ID: {}", new Object[] { conversation.getId() });
        log.info("***     ConversationListener called for session ID: {}", new Object[] { request.getSession().getId() });
    }
}
}
于 2015-03-03T17:18:05.363 回答
1

对话超时是对话将保持多长时间。它不是对话的永久跟踪器。它并不意味着在请求时保持活动状态。

没有扩展对话概念,但是您可以使用 begin(id) 重新创建对话。该对话中的任何 bean 状态都将丢失。

于 2014-12-16T01:22:08.123 回答
1

我发现可以通过使用 Primefaces' 定期调用会话范围 bean 上的方法来防止会话过期p:poll,配置为使用合理的间隔(5 分钟间隔对我有用),不需要花哨的魔法。

于 2017-12-13T17:37:56.753 回答
0

这可能是特定于实现的,但如果您begin()像这样开始对话,框架应该附加一个对话 id 作为请求参数。这就是将对话映射到请求的方式。

使用焊接作为 cdi 实现,这应该是“cid”。我不知道其他实现如何处理对话。

尝试将参数附加到您的心跳请求,它应该映射对话并可能刷新超时。

希望有帮助

于 2014-12-17T20:32:30.880 回答