jsf-2 - CDI @ConversationScoped 与 AJAX

标签 jsf-2 java-ee-6 cdi

我有一个非常典型的 CRUD 情况,我正在苦苦挣扎,所以我想我一定是误解了一些东西。我整理了一个小演示应用程序来更好地解释我的问题。感兴趣的两个文件如下所示:

PersonView - 支持 JSF 页面的 CDI 托管 Bean

package example

import java.io.Serializable;
import java.util.List;
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
import javax.enterprise.inject.Produces;
import javax.inject.Inject;
import javax.inject.Named;

@ConversationScoped @Named
public class PersonView implements Serializable {

private Person selectedPerson;
@Inject private PersonService personService;
@Inject private Conversation conversation;

public PersonView() {}

public List<Person> getPeople() { return personService.findAll(); }

public void beginConversation() { if( conversation.isTransient() ) {conversation.begin();} }

public void endConversation() { if( !conversation.isTransient() ) { conversation.end();} }

public void createPerson() {
    beginConversation();
    setSelectedPerson( new Person() );
}

public void addPerson() {
    personService.addPerson( getSelectedPerson() );
    endConversation();
}

public void updatePerson() { personService.updatePerson( getSelectedPerson() ); }

public Person getSelectedPerson() { return selectedPerson; }

public void setSelectedPerson(Person selectedPerson) { this.selectedPerson = selectedPerson; }
}

index.xhtml - 用于操纵人的 JSF 页面
<?xml version='1.0' encoding='UTF-8' ?>
<!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:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  xmlns:p="http://primefaces.org/ui">
<h:head>
    <title>CRUD Example</title>
</h:head>
<h:body>
    <h:form prependId="false">
        <p:dataTable var="p" value="#{personView.people}" id="person_table" rowKey="#{p.id}" selection="#{personView.selectedPerson}">
            <p:column selectionMode="single"/>              
            <p:column><f:facet name="header">ID</f:facet>#{p.id}<p:column>
            <p:column><f:facet name="header">Name</f:facet>#{p.name}</p:column>
            <f:facet name="footer">
               <p:commandButton value="Create Person" onclick="create_dialog.show();" actionListener="#{personView.createPerson}"/>                 
               <p:commandButton value="Edit Person" onclick="edit_dialog.show();" update="edit_panel"/>
            </f:facet>
        </p:dataTable>
    </h:form>
    <p:dialog header="Create Person" id="create_dialog" widgetVar="create_dialog" modal="true" width="750" height="300">
        <h:form prependId="false">
            <p:panel id="create_panel">
                <p>Name: <p:inputText value="#{personView.selectedPerson.name}" required="true"/></p>
                <p><p:commandButton value="Add" actionListener="#{personView.addPerson}" oncomplete="create_dialog.hide();" update="person_table" /></p>
            </p:panel>
        </h:form>
    </p:dialog>
</h:body>

在索引页面上,用户会看到一个包含系统认识的所有人的数据表。然后他们按下表格底部的“创建人员”按钮。我已经检查过这是否正确调用了 createPerson 方法,并且对话显然开始了。然后会显示 create_dialog,用户可以在其中输入名称。当用户单击“添加”按钮时,问题就出现了。 JSF 尝试存储人员姓名,但 selectedPerson 变量现在为 null,因此它失败并返回 NullPointerException。

我意识到这不是创建对象的常用方法,但在我当前的应用程序中是有道理的,因为我可以猜测新 Person 的一些值。它也非常符合我想要进行编辑的方式。

所以我的问题是:为什么对话没有传播? PersonView bean 似乎一直在请求范围内。我在 JSF2 中读过 @ViewScoped,但如果可能的话,我宁愿坚持使用 CDI。从我读过的内容来看,我认为问题是无法通过请求传递 CID 名称,但我不知道如何使用 AJAX 来做到这一点。

我想出的唯一解决方案是将 PersonView 移动到 session 中,但这感觉就像是一个巨大的麻烦。
电子

最佳答案

我让它工作的唯一方法是在 MyFaces CODI 中使用 @ViewAccessScoped . CDI 允许可扩展性,因此您所要做的就是在您的应用程序中包含 CODI jar 文件。即使您使用的是 Mojarra 而不是 MyFaces,这也有效。

因此,如果您想使用 CDI 注释,那是我的建议。我尝试使用 ConversationScoped 注释有一段时间,但我无法方便地使用它。一旦我开始使用 CODI,我所有的问题都消失了。

关于jsf-2 - CDI @ConversationScoped 与 AJAX,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8049294/

相关文章:

jsf - 在 Primefaces 中对树节点进行排序

java - EJB 3.1 - 在 EJB 中使用 @EJB - 可能吗?

jakarta-ee - Java EE 6 CDI 实现之间的差异

Java EE 7 CDI 手动实例化

java - 什么是 CDI bean?

java - 在 JSF2/Primefaces 中动态添加/删除组件

jsf - 仅在第一个 h :messages component 中显示全局面孔消息

jsf - 如何在响应呈现之前处理多个提交?

classpath - 错误 listenerStart - JaxWS - JBoss as 7

glassfish-3 - GlassFish 3.1.1 b12 上的 CDI 生成错误 "WELD-001408 Unsatisfied dependencies"