2

我在理解 Weld 或 CDI 的对话范围时遇到了一些问题。

在我的 JSF Faclets 页面中,我调用:

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

豆子:

import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
@Named
@ConversationScoped
public class ViewBean implements Serializable {

@Inject
    private Conversation conversation;

public void start() {
    if (conversation.isTransient()) {
        System.out.println("START CONVERSATION");
        conversation.begin();

    }
}

现在每次我刷新浏览器时,都会开始一个新的对话。这是正确的行为吗?那么为什么谈话总是短暂的呢?不会抛出异常。beans.xml 已创建且为空:

<beans xmlns="http://java.sun.com/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>
4

1 回答 1

5

简短回答:是的,这是正确的行为。

长答案:对话代表一个“工作单元”,必须明确划分。这是通过对 conversation.begin() 的显式调用完成的 - 正如您已经在做的那样。如果您想对多个请求使用相同的对话,则必须传播它 - 这就是您没有做的 :-)

当您传播对话时,会在请求中附加一个对话 ID。这告诉容器需要哪个对话。当您在请求中点击没有对话 ID 的刷新按钮时,会为每个请求生成一个新对话。

从文档中:

对话上下文会随任何 JSF 面孔请求(JSF 表单提交)或重定向自动传播。它不会自动传播非人脸请求,例如通过链接导航。

如果您需要手动传播它,只需将会话 ID 添加到请求中:

<h:link outcome="/addProduct.xhtml" value="Add Product">
   <f:param name="cid" value="#{javax.enterprise.context.conversation.id}"/>
</h:link>

这里解释了所有这些以及更多内容。

于 2011-03-30T17:02:03.043 回答