I am creating a Timesheet application using JSF and am currently working on the login portion. It's a straight forward login that takes a login ID and a password and checks if it is a valid combination (though at this point I am just working on administrator login).
My problem seems to be that JSF is not updating my loginID and password fields before calling the verify action method because when I click login, it throws a NullPointerException. Here is my verify method.
/**
* Verifies that the loginID and password is the super user combination.
* @return true if it is, false if it is not.
*/
public String verifyUser() {
ResourceBundle login = getSuperUserLogin();
String user = getLoginID();
String checkPassword = getPassword();
if(!login.containsKey(user) || !checkPassword.equals(login.getString(user))) {
return "regular";
}
return "super";
}
and my login page
<body>
<div class = "content" align = "center">
<h:form>
<h3>#{msgs.loginTitle}</h3>
<h:panelGrid columns="2" cellpadding = "4">
<h:outputText value = "#{msgs.userID}" styleClass="title" />
<h:inputText value="#{user.loginID}" styleClass="rounded" />
<h:outputText value = "#{msgs.password}" styleClass="title" />
<h:inputSecret value="#{user.password}" styleClass="rounded" />
</h:panelGrid>
<p><h:commandButton value="#{msgs.login}" styleClass="button" action="#{superUser.verifyUser}"/></p>
</h:form>
</div>
Now if I hardcode the login ID and password into the user and checkPassword fields, then it works no problem. So I figure that the problem be that loginID and password fields are null (as getLoginID() and getPassword() are just regular old getters that return those fields). I know the answer is going to be something silly and that I am going to feel embarrassed for missing it but I am hitting my head on a wall at this point.
Just so information is complete, the loginID and password fields are located in the a User class (with appropriate setters provided), while the verifyUser method is located in a subclass SuperUser. I don't know why if this would matter at all, but this would be my first JSF application using super and subclasses so you never know.
Edit: On request here is my User class code
package ca.bcit.infosys.timesheet.model;
import java.util.ResourceBundle;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;
@Named
@ApplicationScoped
public class User implements java.io.Serializable {
/** The user's name */
private String name;
/** The user's employee number */
private int empNumber;
/** The user's login ID */
private String loginID;
/** The user's password */
private String password;
/** Is the user currently in an editable state (i.e. the user's information can be edited on the webpage) */
private boolean editable;
private ResourceBundle superUserLogin = ResourceBundle.getBundle("ca.bcit.infosys.timesheet.model.messages");
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the empNumber
*/
public int getEmpNumber() {
return empNumber;
}
/**
* @param empNumber the empNumber to set
*/
public void setEmpNumber(int empNumber) {
this.empNumber = empNumber;
}
/**
* @return the loginID
*/
public String getLoginID() {
return loginID;
}
/**
* @param loginID the loginID to set
*/
public void setLoginID(String loginID) {
this.loginID = loginID;
}
/**
* @return the password
*/
public String getPassword() {
return password;
}
/**
* @param password the password to set
*/
public void setPassword(String password) {
this.password = password;
}
/**
* @return the isEditable
*/
public boolean isEditable() {
return editable;
}
/**
* @param isEditable the isEditable to set
*/
public void setEditable(boolean editable) {
this.editable = editable;
}
/**
* @return the Property containing the super user login information.
*/
public ResourceBundle getSuperUserLogin() {
return superUserLogin;
}
}