0

I am new to JSF and have a login page. Here it is:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>

</h:head>
<h:body>

    <h:form>
        <h:panelGrid columns="2" border="1">
            <h:outputText value="User:"></h:outputText>
            <h:inputText id="username" value="#{login.username}"></h:inputText>
            <h:outputText value="Password"></h:outputText>
            <h:inputSecret  id="password" value="#{login.password}"></h:inputSecret>
            <h:commandButton value="Login" action="#{login.checkDB}"></h:commandButton>

        </h:panelGrid>
    </h:form>
</h:body>
</html>

And here is the Login jsf page

@Named(value = "login")
@Dependent
@RequestScoped
public class Login{

private String username = "", password = "";

public String getUsername() {
    return username;
}

public String getPassword() {
    return password;
}

public void setUsername(String Username) {
    username = Username;
}

public void setPassword(String Password) {
    password = Password;
}

public void checkDB() {
    try {
        con=DB.connect();
        PreparedStatement checkDB = (PreparedStatement) con.prepareStatement(
                "SELECT * FROM Users where username = ? AND password = ?");
        checkDB.setString(1, username);
        checkDB.setString(2, password);
        ResultSet rs = null;
        rs = (ResultSet) checkDB.executeQuery();

        if (rs.next()) {
            User.customer = new Customer(rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getString(5), rs.getString(6), rs.getString(7));
            rs.close();
            DB.disconnect(con);
            FacesContext.getCurrentInstance().getExternalContext().redirect("main.xhtml");            

        } else {
            rs.close();

            DB.disconnect(con);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}
}

And here is the User class:

@ManagedBean(name = "user")
@SessionScoped
public class User implements Serializable {

public static Customer customer;
private Connection con=null;
public void setCustomer(Customer customer) {
    User.customer = customer;
}

public Customer getCustomer() {
    return customer;
}

public User() {
}

public void editInfo() {
    String name = customer.getName(), surname = customer.getSurname(), password = customer.getPassword();
    String phone = customer.getPhone(), address = customer.getAddress(), email = customer.getEmail();


    try {
        con=DBConnect.connect();
        int result = -1;
        PreparedStatement checkDB = (PreparedStatement) con.prepareStatement(
                "UPDATE users set password=?,name=?,surname=?,phone=?,address=?,"
                + "email=? where username=?");
        checkDB.setString(7, customer.getUsername());
        checkDB.setString(1, password);
        checkDB.setString(2, name);
        checkDB.setString(3, surname);
        checkDB.setString(4, phone);
        checkDB.setString(5, address);
        checkDB.setString(6, email);
        result = checkDB.executeUpdate();
        con.close();
        FacesContext.getCurrentInstance().getExternalContext().redirect("editsuccesfull.xhtml");

    } catch (Exception e) {
        e.printStackTrace();
    }

}

The problem is, after username and password are set by the setter functions, they sudenly become null when the function returns from the managed bean. Why is this happening? How can i fix it?

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332

1 Answers1

1

The setters are working right otherwise you would get a NullPointerException in your Login#checkDB method. The problem is that looks like your Login managed bean is marked as @RequestScoped or @ViewScoped (its @RequestScoped after your edition) and you're doing a redirect to main.xhtml instead of forwarding, noticed by this line:

FacesContext.getCurrentInstance().getExternalContext().redirect("main.xhtml");

Note that you're manually creating an instance of User class inside your Login#checkDB method, so it will behave as a POJO and at the end of the method it will be marked for garbage collection (this is basic Java). Also, note that when executing a redirect all the request attributes are lost.

To solve your problem you should save the user data in session instead and let the CDI container manage the beans instead of doing it manually. To do this, you would need to inject the @SessionScoped managed bean to handle the user data (except for the password to avoid security issues). This is explained here: Get access to session scoped CDI bean from request scoped CDI Bean (note that this Q/A provides an example on login as you are looking for).

IMPORTANT NOTE: Do not mix JSF with CDI beans, you should use one or another, but NEVER BOTH AT THE SAME TIME. Change your User bean from @ManagedBean to @Named to work with CDI power.

Community
  • 1
  • 1
Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
  • Actually i thought i started a session by User.customer = new Customer(rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getString(5), rs.getString(6), rs.getString(7)); in Login bean, i edited question and put the User class, it is session scoped. Is this a wrong way to do? –  Jul 04 '13 at 17:44
  • Thank you i think i figured out how to use FacesContext for session issues –  Jul 04 '13 at 21:02