我要求保持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秒发一次文字。但谈话仍然有效。
答案 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分钟的间隔对我有用),不需要花哨的魔法。