如何让Primefaces与@ConversationScoped Beans一起使用?

时间:2012-07-28 15:28:12

标签: jsf tomcat primefaces cdi myfaces

我使用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 然后每次点击'increment'按钮都会抓取一个新的Bean实例,因为cid-Parameter没有传递给Server。有人指出,这不是一个主要问题。但为什么它使用标准组件而不是主要组件? 我已经能够通过明确地将 f:param 组件嵌入到commandButton组件中来传递cid-Parameter,但是在销毁Conversation之后,发送的参数没有产生错误的值。但它甚至应该没有 f:param 组件。

是否有一个简短的教程如何使用Primefaces和Conversation scoped bean(没有明确地传递cid-Parameter)?

2 个答案:

答案 0 :(得分:0)

在结束会话的情况下,f:param的问题在于,参数cid不应使用无效值(null)传递参数。所以使用以下代码纠正这个问题很有效:

<!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)组件一样。

答案 1 :(得分:0)

<h:commandButton><p:commandButton>之间的一个显着区别是PrimeFaces品种默认使用AJAX。您似乎在某种程度上了解这一点,因为您一直在调整update的{​​{1}}参数以使视图更新。

考虑到这一点,如果你自己使用<p:commandbutton>定期<f:ajax>,我猜你会遇到同样的问题,这表明它并不是特定的PrimeFaces问题。

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

increment()

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

相关问题