提交表单时对话不会自动传播?

发布于 2024-12-22 06:53:59 字数 2553 浏览 1 评论 0原文

我有以下对话范围的支持 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: 创建 TestConversation bean!!! 这是正确的。

但随后我点击 h:commandLink 并看到:

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

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

引用自 docs:

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

如果我添加此 那么一切正常。难道是我有什么误解?

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

I have the following conversation scoped backing 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;
    }
}

And the following facelets view:

<!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>

When I enter the page I see INFO: Creating TestConversation bean!!! which is correct.

But then I click on the h:commandLink and I see:

INFO: Creating TestConversation bean!!!
INFO: Invoking commandLinkAction

The bean was created again, which means that the conversation was not propagated. I think this contradicts with the following:

Quote from docs:

The long-running conversation context associated with a request that renders a JSF view is automatically propagated to any faces request (JSF form submission) that originates from that rendered page.

If I add this <f:param name="cid" value="#{javax.enterprise.context.conversation.id}"/> then everything works fine. Do I have a misunderstanding?

P.S Without the f:param it works fine when I click on the commandLink for the second time, but not on the first time:(.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

淡紫姑娘! 2024-12-29 06:53:59

我想,问题似乎是在处理 组件时没有开始对话,因此表单的操作第一次没有 cid。第二

次,当您单击链接 testConversation.commandLinkAction 时,访问 testConversation 会在处理 之前启动对话

尝试这 则更改以下内容

如果将 #{testConversation} 放在 之前,
示例工作正常,因为在处理 之前开始对话

希望这有帮助..

I guess, the problem seems like conversation was not started when the <h:form> component was processed so the form's action did not had cid in it for the first time..

For the second time, when you click on a link, testConversation.commandLinkAction, access to testConversation made the conversation to start before processing the <h:form>

try the below change

If you place #{testConversation} before <h:form>
example works fine as converation is started before processing the <h:form>

Hope this helps..

情深已缘浅 2024-12-29 06:53:59

基于前面的答案,这肯定是因为 TestConversation bean 没有被构造,直到表单自动包含 cid 时已经太晚了。

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

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

将其放在 Facelet 模板的早期位置,例如在 f:metadata 中(因为它通常与 f:viewParam 结合使用),并删除 @PostConstruct 注释。这使得 init 的调用变得显式,而不是依赖它作为正在构造的 bean 的副作用来运行,因为它是在 EL 表达式中引用的。

Building on the previous answer, it's definitely because the TestConversation bean is not being constructed until it's already too late for the form to include the cid automatically.

In this case, you're initializing data for the view, so it's probably better to put it in a preRenderView event listener instead.

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

Put this early in your facelet template, such as in the f:metadata (as it's often used in conjunction with f:viewParam), and remove the @PostConstruct annotation. That makes the invocation of init explicit rather than relying on it being run as a side effect of the bean being constructed because it was referenced in an EL expression.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文