0

私は JSF を初めて使用し、ログイン ページを持っています。ここにあります:

<?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>

そして、これがログインjsfページです

@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();
    }
}
}

そして、ここにユーザークラスがあります:

@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();
    }

}

問題は、セッター関数によってユーザー名とパスワードが設定された後、マネージド Bean から関数が戻ると突然 null になることです。なぜこうなった?どうすれば修正できますか?

4

1 に答える 1

1

セッターは正しく機能しています。そうしないと、メソッドで a が取得NullPointerExceptionされますLogin#checkDBLogin問題は、管理対象 Bean が@RequestScopedorとしてマークされているように見え@ViewScoped(@RequestScopedエディションの後)、転送ではなくmain.xhtmlへのリダイレクトを行っていることです。次の行に注意してください。

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

Userメソッド内でクラスのインスタンスを手動で作成しているLogin#checkDBため、POJO として動作し、メソッドの最後でガベージ コレクションのマークが付けられることに注意してください (これは基本的な Java です)。また、リダイレクトを実行すると、すべてのリクエスト属性が失われることに注意してください。

問題を解決するには、代わりにユーザー データをセッションに保存し、CDI コンテナーに手動で行う代わりに Bean を管理させる必要があります。これを行うには、@SessionScopedマネージド Bean を注入してユーザー データを処理する必要があります (セキュリティ上の問題を回避するためのパスワードを除く)。これはここで説明されています:リクエスト スコープ CDI Bean からセッション スコープ CDI Bean へのアクセスを取得します(この Q/A は、探しているログインの例を提供することに注意してください)。

重要な注意: JSF と CDI Bean を混在させないでください。いずれかを使用する必要がありますが、両方を同時に使用しないでください。UserBean を から@ManagedBeanに変更して@Named、CDI パワーで動作するようにします。

于 2013-07-04T17:40:26.350 に答える