【问题标题】:Setter methods do not work in JSFSetter 方法在 JSF 中不起作用
【发布时间】:2013-07-04 17:37:13
【问题描述】:

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

}

问题是,在setter函数设置用户名和密码后,当函数从托管bean返回时,它们突然变为null。为什么会这样?我该如何解决?

【问题讨论】:

  • 你的 bean 是请求范围的
  • @KorayTugay 这不是这里唯一的问题。
  • 为什么你发布相同的后续问题,而不是调查我对that question 的回答中提到的要点?此外,不鼓励在 SO 上拥有多个帐户。
  • @skuntsel 这些问题看起来很相似,但我不确定是不是同一个人。
  • @LuiggiMendoza 我认为是这样,因为大部分代码基本上都是在这里复制粘贴的。或者可能有一个团队正在解决相同的登录问题:)

标签: java jsf javabeans


【解决方案1】:

setter 工作正常,否则您将在 Login#checkDB 方法中获得 NullPointerException。问题是,看起来您的 Login 托管 bean 被标记为 @RequestScoped 或 @ViewScoped(在您的版本之后是 @RequestScoped),而您正在重定向到 main.xhtml转发,由这一行注意到:

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

请注意,您是在 Login#checkDB 方法中手动创建 User 类的实例,因此它将表现为 POJO,并且在方法结束时将标记为垃圾回收(这是基本的 Java )。另外,请注意,执行重定向时,所有请求属性都会丢失。

要解决您的问题,您应该将用户数据保存在会话中,并让 CDI 容器管理 bean 而不是手动进行。为此,您需要注入 @SessionScoped 托管 bean 来处理用户数据(避免安全问题的密码除外)。此处对此进行了解释:Get access to session scoped CDI bean from request scoped CDI Bean(请注意,此 Q/A 提供了您正在寻找的登录示例)。

重要提示:不要将 JSF 与 CDI bean 混合使用,您应该使用一种或另一种,但切勿同时使用两种方法。将 User bean 从 @ManagedBean 更改为 @Named 以使用 CDI 电源。

【讨论】:

  • 其实我以为我通过 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));在登录 bean 中,我编辑了问题并放置了 User 类,它是会话范围的。这是错误的做法吗?
  • 谢谢你,我想我知道如何使用 FacesContext 解决会话问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-11
  • 2019-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-04
相关资源
最近更新 更多