如何防止JSF对话过期

时间:2014-12-15 20:56:48

标签: cdi jsf-2.2 conversation-scope

我要求保持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();
}
}

打印" Heartbeat Recieved"每5秒发一次文字。但谈话仍然有效。

4 个答案:

答案 0 :(得分:1)

对话超时是对话保持活跃的时间。它不是会话的永久跟踪者。它并不意味着要求保持活力。

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

答案 1 :(得分:1)

我们遇到了同样的问题。添加" cid"对servlet的请求没有帮助。根据我们的经验,心跳Servlet不了解对话。它将保持当前会话的进行,但不会对会话提供帮助。

我们的解决方案是添加一个视图结构的托管bean,我们在其中注入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() });
    }
}
}

答案 2 :(得分:0)

这可能是实现规范,但如果您像{J}一样开始与begin()对话,则框架应将会话ID附加为请求参数。这就是对话如何映射到请求。

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

尝试将参数附加到心跳请求中,它应该映射会话并刷新超时。

希望有所帮助

答案 3 :(得分:0)

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