【问题标题】:Conversation not propagated automatically on form submission?表单提交时对话不会自动传播?
【发布时间】:2011-12-18 14:46:28
【问题描述】:

我有以下会话范围的支持 bean:

@Named
@ConversationScoped
public class TestConversation implements Serializable {

    private Logger logger = LoggerFactory.getLogger(TestConversation.class);

    private List<Integer> numbers;

    @Inject
    private Conversation conversation;

    @PostConstruct
    public void init() {
        logger.info("Creating TestConversation bean!!!");

        numbers = new ArrayList<Integer>();
        numbers.add(3);
        numbers.add(4);
        numbers.add(5);
        numbers.add(6);

        conversation.begin();        
    }

    public void commandLinkAction() {
        logger.info("Invoking commandLinkAction");
    }

    public List<Integer> getNumbers() {
        return numbers;
    }
}

以及以下 facelets 视图:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">

    <h:head>
        <title>Testing Conversation</title>        
    </h:head>

    <h:body>
        <h:form>
            <h:dataTable value="#{testConversation.numbers}" var="num">
                <h:column>                    
                    <h:outputText value="#{num}"/>
                </h:column>
                <h:column>                    
                    <h:commandLink action="#{testConversation.commandLinkAction}">Trigger form submission</h:commandLink>
                </h:column>
            </h:dataTable>
        </h:form>
    </h:body>
</html>

当我进入页面时,我看到INFO: Creating TestConversation bean!!! 这是正确的。

然后我点击h:commandLink,我看到了:

信息:创建 TestConversation bean!!!
信息:调用 commandLinkAction

再次创建了 bean,这意味着对话没有传播。我认为这与以下内容相矛盾:

引用docs:

与呈现 JSF 视图的请求关联的长时间运行的对话上下文会自动传播到源自该呈现页面的任何面孔请求(JSF 表单提交)。

如果我添加此&lt;f:param name="cid" value="#{javax.enterprise.context.conversation.id}"/&gt;,那么一切正常。我是不是有什么误会?

P.S 如果没有f:param,当我第二次单击commandLink 时它可以正常工作,但不是第一次:(。

【问题讨论】:

    标签: java jsf cdi conversation-scope


    【解决方案1】:

    我想,问题似乎是在处理 &lt;h:form&gt; 组件时没有开始对话,因此表单的操作第一次没有 cid ..

    第二次,当您点击链接时,testConversation.commandLinkAction 访问 testConversation 在处理 &lt;h:form&gt; 之前开始对话

    尝试以下更改

    如果您将#{testConversation} 放在&lt;h:form&gt; 之前 示例工作正常,因为在处理 &lt;h:form&gt; 之前开始了对话

    希望这会有所帮助..

    【讨论】:

      【解决方案2】:

      在上一个答案的基础上,这肯定是因为 TestConversation bean 没有被构造,直到表单自动包含 cid 已经太晚了。

      在这种情况下,您正在为视图初始化数据,因此最好将其放在 preRenderView 事件侦听器中。

      <f:event type="preRenderView" listener="#{testConversation.init}"/>
      

      把它放在你的 facelet 模板的早期,比如 f:metadata(因为它经常与 f:viewParam 一起使用),并删除 @PostConstruct 注释。这使得init 的调用显式而不是依赖它作为正在构建的 bean 的副作用运行,因为它在 EL 表达式中被引用。

      【讨论】:

      • 感谢它以这种方式工作。但我讨厌这个preRenderView 也会因为ajax 请求而触发。我必须在 init 方法中检查 conversation.isTransient() 以避免异常。
      猜你喜欢
      • 1970-01-01
      • 2012-03-13
      • 2016-08-18
      • 2015-05-14
      • 1970-01-01
      • 2019-03-23
      • 1970-01-01
      • 2019-09-24
      • 1970-01-01
      相关资源
      最近更新 更多