【问题标题】:Nullpointer exception when using @RequestScoped bean使用 @RequestScoped bean 时出现 Nullpointer 异常
【发布时间】:2026-01-11 18:10:01
【问题描述】:

我正忙于使用 JavaEE6、JSF 2.0 和 CDI 编写一个非常简单的登录页面。 我的登录页面如下所示(为清楚起见,删除了一些内容):

<html>
    <head>
        <title>HomeBase - Login</title>
    </head>
    <body>
        <h3>Login</h3>
        <h:form>
            <div>
                <label>UserID:</label>
                <h:inputText value="#{loginBean.userid}" />
            </div>
            <div>
                <label>Password:</label>
                <h:inputSecret value="#{loginBean.password}" />
            </div>
            <h:commandButton value="Login" action="#{loginBean.login}" />
        </h:form>
    </body>
</html>

backingbean 如下所示:

@ManagedBean
@RequestScoped
public class LoginBean implements Serializable {

    @Inject Logger LOG;

    private String userid;

    private String password;

    public String login() {
        LOG.info("Start login procedure.");
        if ("gast".equalsIgnoreCase(userid) && "gast".equals(password)) {
            SessionBean sessionBean = (SessionBean) FacesContext.getCurrentInstance()
                    .getExternalContext().getSessionMap().get("sessionBean");
            User user = new User();
            user.setUserid(userid);
            user.setPassword(password);
            user.setUsername("Gast");
            sessionBean.setUser(user);
            return "loginSuccess";
        }

        return "loginFailure";
    }

    public String getUserid() {
        return userid;
    }

    public void setUserid(String userid) {
        this.userid = userid;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

现在,当我调用登录页面时,它会正确显示。两个输入字段都是空的。在调试模式下,我可以看到两个字段值的 getter 都被调用了。接下来,我填写字段并按下提交按钮,然后立即发生空指针异常。显然 LoginBean 是第一次(显示页面时),但不是当我按下命令按钮时。

发生了什么?

【问题讨论】:

  • NPE 的堆栈跟踪将指向您登录方法中的一行。

标签: jsf-2 nullpointerexception java-ee-6 managed-bean


【解决方案1】:

CDI @Inject 在 JSF @ManagedBean 中不起作用。因此LOG 仍然是null

使用 CDI @Named 而不是 JSF @ManagedBean 并确保从 CDI javax.enterprise.context 包而不是 JSF javax.faces.bean 导入 @RequestScoped 注释。

【讨论】:

  • 如果注入的 bean 符合注入条件,则注入应该起作用。注入可能由于某些其他原因而失败。我的赌注也在记录仪上。
  • 我暂时从代码中删除了所有日志记录功能,但问题仍然存在。我仍然得到空指针异常。但是,当我删除@ManagedBean 并添加@Named 时,当我按下登录按钮时,我在#{loginBean.userid} 属性上得到一个PropertyNotFound 异常。 @Named 注解的类的默认名称是首字母不大写的类名,即“loginBean”。所以这个异常有点出乎意料,虽然不是真的,因为它归结为和以前一样的问题,不存在 LoginBean 类的实例。