21

我正在尝试处理@javax.faces.bean.ManagedProperty但没有成功!

我一直在关注指南,似乎并不难。但是我的代码根本行不通!

这是一个小片段

@ManagedBean
@SessionScoped
public class LoginBean {

    private User user;

    // ...
}
@Named
@RequestScoped
public class MessagesBean {

    @ManagedProperty(value = "#{loginBean}")
    private LoginBean loginBean;

    public String getUser() {
        System.err.println(loginBean == null);
        return loginBean.getUser().getUsername();
    }

    // ...
}

这段代码给了我一个NullPointerException,说它loginBean是空的!

有什么建议吗?

4

1 回答 1

42

您正在将 JSF 托管 bean 与 CDI bean 混合。您的LoginBean是一个 JSF 托管 bean(它具有@ManagedBean注释)。您的MessageBean是一个 CDI bean(它具有@Named注释)。如果您将 Message bean 更改为 JSF 托管 bean(替换@Named@ManagedBean),那么问题应该得到解决(它也应该与两个 CDI bean 一起使用)。或者,如果您使用的是 JSF 2.3 或更新版本,那么javax.faces.annotation.ManagedProperty请在 CDI bean 中使用。

下面简要介绍两种 bean 类型之间的注入工作原理:

CDI @Named --> CDI @Named(有效)

CDI @Named --> JSF @ManagedBean(仅在注入 bean 的范围更广时才有效)

JSF @ManagedBean --> JSF @ManagedBean(仅在注入 bean 的范围更广时有效)

JSF @ManagedBean --> CDI @Named(不起作用)

但请注意范围导入类。根据 bean 类型,@SessionScoped有不同的类。@RequestScoped

javax.faces.bean.SessionScoped对于@ManagedBeans

javax.enterprise.context.SessionScoped对于 CDI @Named bean

此外,供@Named(CDI)使用@Inject和供@ManagedBean使用@ManagedProperty。有一件事在 CDI 中不起作用。你@ManagedProperty(value = "#{loginBean}")得到一个完整的bean,但@ManagedProperty(value = "#{loginBean.user}")要获得一个bean的“属性”就可以了。这在带有@Inject. 有关“解决方案”,请参阅@ManagedProperty 的 CDI 替换

于 2012-03-29T08:10:20.160 回答