我正在使用 EJB、JPA 和 JSF 制作一个简单的登录 Web 应用程序。我有一个login.xhtml
带有传递 aUserName
和Password
into的表单的页面LoginJSFBean
,它调用我的 EJB 方法LoginBean.validate
来查找 MySQL 数据库。如果凭据有效,它会设置customerId
in的值LoginJSFBean
并加载欢迎页面。我正在尝试将其注入LoginJSFBean
到我的CustomerJSFBean
via@ManagedProperty
中,这样我就可以保留 的值,customerId
以便创建具有Customer
该 的对象id
。但是,我不断收到以下错误:
javax.servlet.ServletException: Cannot invoke "bean.LoginJSFBean.getCustomerId()" because "this.loginJSFBean" is null
这是我的代码:
登录.xhtml:
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<head>
<title>Login</title>
</head>
<body>
<h2>Login</h2>
<h:outputText value="#{LoginBean.login.errorMsg}"
rendered="#{LoginBean.login.errorMsg != null}" style="color:red;" />
<h:form>
User Name: <h:inputText id="userName" value="#{LoginBean.login.userName}"/><br />
Password: <h:inputSecret id="password" value="#{LoginBean.login.password}"/><br />
<h:commandButton value="Submit" action="#{LoginBean.validate}" />
</h:form>
</body>
</html>
欢迎.xhtml:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html">
<head>
<title>Insert title here</title>
</head>
<body>
<h2>Welcome <h:outputLabel class="successText" value="#{CustomerBean.customer.id}"/> !</h2>
You are successfully logged in
</body>
</html>
登录JSFBean.java:
package bean;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import dto.LoginDTO;
import ejb.LoginBeanRemote;
@ManagedBean(name = "LoginBean", eager = true)
@SessionScoped
public class LoginJSFBean {
private LoginDTO login = new LoginDTO();
private int customerId;
@EJB
LoginBeanRemote loginBean;
public LoginDTO getLogin() {
return login;
}
public void setLogin(LoginDTO login) {
this.login = login;
}
public int getCustomerId() {
return customerId;
}
public void setCustomerId(int customerId) {
this.customerId = customerId;
}
public String validate() {
if (loginBean.validate(login.getUserName(), login.getPassword())) {
login.setErrorMsg(null);
setCustomerId(loginBean.getCustomerId(login.getUserName()));
return "welcome";
} else {
login.setErrorMsg("Invalid user id or password. Please try again");
return null;
}
}
}
客户JSFBean.java:
package bean;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import dto.CustomerDTO;
import ejb.CustomerBeanRemote;
@ManagedBean(name = "CustomerBean", eager = true)
@SessionScoped
public class CustomerJSFBean {
@ManagedProperty(value = "#{LoginBean}")
private LoginJSFBean loginJSFBean;
private CustomerDTO customer = new CustomerDTO(loginJSFBean.getCustomerId());
@EJB
CustomerBeanRemote customerBean;
public CustomerDTO getCustomer() {
return customer;
}
public void setCustomer(CustomerDTO customer) {
this.customer = customer;
}
public LoginJSFBean getLoginJSFBean() {
return loginJSFBean;
}
public void setLoginJSFBean(LoginJSFBean loginJSFBean) {
this.loginJSFBean = loginJSFBean;
}
public List<CustomerDTO> getCustomers() {
return customerBean.getCustomers();
}
}
我觉得这很奇怪,因为如果我CustomerJSFBean.loginJSFBean.customerId
从我的welcome.xhtml
页面中引用它,它会正确显示customerId
并且不会抛出任何错误,这表明注入loginJSFBean
的不是null
. 但是当我尝试从CustomerJSFBean
它声称的内部进行相同的引用loginJSFBean
时null
。这与 JSF 各个部分的执行顺序有关吗?你可能会说,我对这一切都很陌生!