JSF托管bean EJB注入

For*_*rty 18 jsf ejb managed-bean

我在企业应用程序模块中有一个EJB(PersonManager),它注入另一个EJB(Person):

@Stateful
public class PersonManager implements PersonManagerLocal {
    @EJB
    private PersonLocal person;

    @Override
    public void setPersonName(String name) {
        person.setName(name);
    }

    @Override
    public String getPersonName() {
        return person.getName();
    }
}
Run Code Online (Sandbox Code Playgroud)

我想在JSF Web应用程序中使用PersonManager EJB.我在faces-config.xml中定义它:

<managed-bean>
    <managed-bean-name>personManager</managed-bean-name>
    <managed-bean-class>ejb.PersonManager</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>
Run Code Online (Sandbox Code Playgroud)

问题是,不会发生PersonLocal EJB的注入.person属性始终为NULL.我错了什么?

但是如果我在这样的JSF托管bean中注入PersonManager:

@ManagedBean
@RequestScoped
public class Index {
    @EJB
    private PersonManagerLocal personManager;
    ....
Run Code Online (Sandbox Code Playgroud)

有用.我需要第一个场景,请帮助我:-D

Bal*_*usC 40

您正在混合EJB和JSF托管bean的职责.该faces-config.xml寄存器只有JSF的文物,如托管bean,而不是EJB的.您的注册地址faces-config.xml

<managed-bean>
    <managed-bean-name>personManager</managed-bean-name>
    <managed-bean-class>ejb.PersonManager</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
</managed-bean>
Run Code Online (Sandbox Code Playgroud)

基本上完全相同

@ManagedBean
@SessionScoped
public class PersonManager {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

换句话说,您将该类注册为JSF托管bean,该bean在视图中可用#{personManager}.这不代表与EJB容器管理的实例相同的实例.你可以和应该使用faces-config.xml注册的EJB.在那里你使用javax.ejb包中的注释,例如@Stateless@Stateful.这就是注册EJB所需的全部内容.

实际上,注册JSF托管bean faces-config.xml是一种旧的JSF 1.x方式,它在JSF 2.x中被新@ManagedBean注释所取代.


更新正确的方法是:

查看(Facelets文件):

<h:form>
    <h:inputText value="#{personManager.person.name}" />
    ...
    <h:commandButton value="Save" action="#{personManager.save}" />
    <h:messages />
</h:form>
Run Code Online (Sandbox Code Playgroud)

Controller(JSF托管bean):

@ManagedBean
@ViewScoped
public class PersonManager implements Serializable {

    private Person person;

    @EJB
    private PersonService personService;

    @PostConstruct
    public void init() {
        person = new Person();
    }

    public void save() {
        personService.create(person);
        FacesContext.getCurrentInstance().addMessage(null,
            new FacesMessage("Person successfully created, new ID is " + person.getId()));
    }

    // ...
}
Run Code Online (Sandbox Code Playgroud)

模型(JPA实体):

@Entity
public class Person implements Serializable {

    @Id
    private Long id;

    private String name;

    // ...
}
Run Code Online (Sandbox Code Playgroud)

服务(无状态EJB):

@Stateless
public class PersonService {

    @PersistenceContext
    private EntityManager em;

    public void create(Person person) {
        em.persist(person);
    }

    // ...
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,我的答案示例中缺少`@ Stateful`.这不是**这样的EJB.您试图将EJB滥用为JSF托管bean.这个不对.你应该基本上有1个XHTML文件作为View,1个JSF托管bean作为Controller,1个实体作为Model,1个EJB作为服务.在你的问题中,`PersonManager`应该是一个JSF托管bean,而不是EJB.`PersonLocal`似乎是一个实体,而不是EJB.所以我怀疑它是否真的需要成为EJB.EJB旨在提供诸如`create()`,`save()`等服务. (4认同)
  • 我正在阅读答案,同时我正在欣赏作者,但当我到达终点时,我的兴奋因为在底部看到你的名字"BalacC"而减少了.难怪只有你能写出这么好的答案.祝你好运 (2认同)