Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java @为@ConversationScope bean多次调用后构造_Java_Java Ee 6_Cdi_Jboss Weld_Seam Conversation - Fatal编程技术网

Java @为@ConversationScope bean多次调用后构造

Java @为@ConversationScope bean多次调用后构造,java,java-ee-6,cdi,jboss-weld,seam-conversation,Java,Java Ee 6,Cdi,Jboss Weld,Seam Conversation,我有一个@ConversationScope bean,带有一个start方法,如下所示: @PostConstruct public void start() { if (conversation.isTransient()) { conversation.begin(); log.debug("conversation.getId(): " + conversation.getId()); } } 我的问题是每次刷新页面时都会启动一个新的对话

我有一个@ConversationScope bean,带有一个start方法,如下所示:

@PostConstruct
public void start() {
    if (conversation.isTransient()) {
        conversation.begin();
        log.debug("conversation.getId(): " + conversation.getId());
    }
}
我的问题是每次刷新页面时都会启动一个新的对话,每次我对bean中的方法进行AJAX调用时也会启动一个新的对话(这是我的主要问题)

我真正想做的是让sam对话一直挂起,直到我手动调用conversation.end()。我在这里遗漏了什么?

您是否检查了(AJAX)调用是否包含对话ID参数(cid)

如果没有,每次通话都会启动一个新的对话。

都在文档中:

对话范围处于活动状态:

在任何JSF faces或非faces请求的所有标准生命周期阶段

会话上下文提供对与特定会话关联的状态的访问。每个JSF请求都有一个相关的对话。此关联由容器根据以下规则自动管理:

任何JSF请求都只有一个关联的对话。 与JSF请求相关联的对话在恢复视图阶段开始时确定,在请求期间不会更改

任何对话都处于两种状态之一:瞬时或长时间运行

默认情况下,对话是暂时的 通过调用conversation.begin()可以将临时会话标记为长时间运行 长时间运行的对话可以通过调用conversation.end()标记为暂时的

所有长时间运行的会话都有一个字符串值的唯一标识符,该标识符可以在会话标记为长时间运行时由应用程序设置,也可以由容器生成

如果与当前JSF请求相关联的会话在JSF请求结束时处于瞬态,那么它将被销毁,会话上下文也将被销毁

如果与当前JSF请求关联的会话在JSF请求结束时处于长时间运行状态,则不会销毁该会话。相反,可以根据以下规则将其传播到其他请求:

与呈现JSF视图的请求相关联的长时间运行的会话上下文会自动传播到任何源自该呈现页面的faces请求(JSF表单提交)。 与导致JSF重定向(由导航规则或JSF NavigationHandler导致的重定向)的请求相关联的长时间运行的对话上下文将自动传播到生成的非faces请求,以及到相同URL的任何其他后续请求。这是通过使用一个名为cid的GET请求参数来实现的,该参数包含会话的唯一标识符。 与请求相关联的长时间运行的会话可以通过使用名为cid的GET请求参数传播到任何非faces请求,该参数包含会话的唯一标识符。在这种情况下,应用程序必须管理此请求参数

当没有会话传播到JSF请求时,该请求与新的临时会话相关联。所有长时间运行的会话都限定在特定的HTTPServlet会话范围内,并且不能跨越会话边界。在以下情况下,无法还原传播的长时间运行的对话并将其与请求重新关联:

当HTTP servlet会话无效时,在servlet service()方法完成后,当前会话期间创建的所有长时间运行的会话上下文都将被销毁。 为了节省资源,允许容器任意销毁与当前JSF请求无关的任何长时间运行的会话

作者:
加文·金,皮特·缪尔

有点离题,但希望有价值:

我不能100%确定@PostConstruct是否是开始对话的正确地点。我宁愿使用这样的faces事件:

<f:metadata>
        <f:event type="javax.faces.event.PreRenderViewEvent"
                listener="#{myBean.init}" />
</f:metadata>
如果使用Seam 3,则更容易:

<f:metadata>
   <s:viewAction action="#{myBean.init}" if="#{conversation.transient}" />
</f:metadata>

JSR-299内置对话的概念有点不完整。至少对于JSF应用程序。使用@PreRenderViewEvent基本上会放弃这种方法的所有好处,因为它会使每个@ConversationScope bean长时间运行

您可以尝试改用apachemyfacescodi@ConversationScoped。CODI是一个CDI扩展库,已知它可以很好地与ApacheOpenWebBeans和Weld配合使用。 它还提供@ViewScope、@ViewAccessScope(一种自动对话)和@WindowsScoped上下文


更多信息请访问:

IMHO CDI对话因设计而中断,struberg指出了一个很有希望的替代方案。在我的应用程序中,我也遇到了同样的问题,目前我正在将其重构为CDI+CODI 1,感觉很好@ConversationScope解决了所有这些问题。在重构我的应用程序时,我可以用@ViewAccessScope解决很多棘手的问题。谢谢斯特鲁伯格给我们指路

奇怪的是,如果将事件侦听器添加到Facelet中,即使它调用空方法,生成源的form操作也会有“cid”参数,因此AJAX调用不会创建新的对话。如果没有事件侦听器,“cid”在表单操作中缺少

<f:metadata>
    <f:event listener="#{myBean.dummy}" type="preRenderView" />
</f:metadata>

我同意,如果我刷新页面,我真的不想开始新的对话。事实上,如果我给对话命名,并且刷新页面,我会得到一个异常,因为它不能重复使用相同的对话id。如果您可以像Seam 2一样加入对话,那就太好了。我想我会遇到与您的方法相同的问题,但我确实喜欢您的方法而不是使用@PostConstruct的想法。我刚刚尝试过它,它适用于AJAX请求,但如果我刷新页面,我会得到“WELD-000218对话ID myConversation已在使用”。因此,有50%:)。我知道为什么刷新时会发生这种情况,我只是希望我可以让它在刷新时重用当前的对话。我正在确保我的请求
<f:metadata>
    <f:event listener="#{myBean.dummy}" type="preRenderView" />
</f:metadata>
public void dummy() {}