2

我使用 JSF-Compnents 构建了一个短页面,该页面显示并增加了来自 @ConversationScoped Bean 的值。此页面能够结束对话,并在结束旧对话后得到一个新的 Bean。这是它的样子:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
   xmlns:h="http://java.sun.com/jsf/html"
   xmlns:f="http://java.sun.com/jsf/core"
   xmlns:p="http://primefaces.org/ui">
<h:head />
<h:body>
    <h:form>
      <h:outputText id="i" value="#{test.i}" />
      <h:commandButton value="increment" 
         actionListener="#{test.increment}" 
         update="i cid" />
      <h:outputText id="cid" 
         value="#{javax.enterprise.context.conversation.id}" />
      <h:commandButton value="end"
         actionListener="#{test.endConversation}"
         update="i cid" />
    </h:form>
</h:body>
</html>

Bean 的代码非常简单:

package de.burghard.britzke.test.beans;

import java.io.Serializable;

import javax.annotation.PostConstruct;
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.inject.Inject;
import javax.inject.Named;

@Named
@ConversationScoped
public class Test implements Serializable {

   @Inject Conversation conversation;
   private int i;

   @PostConstruct
   public void init() { 
      conversation.begin(); 
      System.out.println("init conversation"+conversation.getId());
   }

   public int getI() {   return i; }
   public void setI(int i) { this.i = i; }

   public void increment() { i++;System.out.println(i); }

   public void endConversation() {
      System.out.println("ending conversation "+conversation.getId());
      conversation.end();
   }
}

使用标准h:commandButton组件时,一切正常。但是使用 Primefaces 组件p:commandButton然后每次单击“增量”按钮都会抓取一个新的 Bean 实例,因为 cid 参数没有传递给服务器。有人说这不是primefaces问题。但是为什么它使用标准组件而不是 primefaces 呢?我已经能够通过将f:param组件显式嵌入到 commandButton 组件中来传递 cid 参数,但是在销毁 Conversation 后,发送的参数没有产生错误的值。但它甚至应该在没有f:param组件的情况下工作。

是否有一个简短的教程如何使用 Primefaces 和对话范围的 bean(没有显式传递 cid 参数)?

4

2 回答 2

0

在结束对话的情况下的问题f:param是,不应使用参数的无效值 (null) 传递参数cid。因此,使用以下代码更正此问题效果很好:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core"
      xmlns:p="http://primefaces.org/ui">
<h:head />
<h:body>
    <h:form id="form">
        <h:outputText value="#{test.i}" />
        <p:commandButton value="increment"
            actionListener="#{test.increment}"
            update="@parent">
            <f:param 
                name="#{not empty javax.enterprise.context.conversation.id?'cid':''}"
                value="#{javax.enterprise.context.conversation.id}" />
        </p:commandButton>
        <h:outputText
            value="#{javax.enterprise.context.conversation.id}" />
        <p:commandButton value="end" actionListener="#{test.endConversation}"
            update="@parent">
            <f:param name="cid" value="#{javax.enterprise.context.conversation.id}" />
        </p:commandButton>
    </h:form>
</h:body>
</html>

但我希望 primefaces 组件无需页面程序员显式传递f:param. 它们的行为应该像标准的 JSF (MyFaces) 组件一样。

于 2012-07-29T12:22:52.180 回答
0

<h:commandButton>和之间的一个显着区别<p:commandButton>是 PrimeFaces 变体默认使用 AJAX。您似乎在某种程度上知道这一点,因为您一直在调整update参数<p:commandbutton>以更新视图。

考虑到这一点,我猜如果您将<f:ajax>自己与常规一起使用,您会遇到同样的问题<h:commandButton>,这表明这不是 PrimeFaces 问题。

至于您的实际问题,我不能肯定地说,但我遇到了在建立会话的同一请求中开始对话的问题。要对此进行测试,您可以尝试从链接到此测试页面的单独页面开始,或者代替您的@PostConstruct方法,将其放在方法的开头increment()

if (conversation.isTransient()) {
    conversation.begin();
}

我知道这不能解决您的问题,但也许它可以为您提供足够的信息来解决它。

于 2012-07-30T18:06:17.010 回答