【问题标题】:class variable set to null outside of a servlet类变量在 servlet 之外设置为 null
【发布时间】:2014-02-22 12:14:39
【问题描述】:

我写了一个简单的servlet,在doPost中我从一个jspand获得了用户名和密码,通过将用户输入的密码发送到数据库(mysql)来验证用户。我正确获取了数据,我将用户重定向到另一个名为welcome.jsp 的jsp 页面。

我的问题是,我写了这个方法 public String getUser(){return userNmae;};我把它放在dopost方法之外,但是它返回null。我已经将变量userNmae声明为类变量,当我调试时,该变量在dopost方法中包含一个值,但是在dopost方法之外它是null。为什么它在dopost方法之外是null?

我在welcome.jsp 页面中调用getUser() 方法。 这是我的代码

public class UIclass extends HttpServlet {
    public UIclass() { };
    private String passWord = null;
    private String userNmae = null;

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String name = request.getParameter("userName");
        String password = request.getParameter("password");
        Connection connection = null;

        try {
            connection = Connections.getConnection();
            java.sql.PreparedStatement statement = connection.prepareStatement("SELECT PASSWORD,USERNAME FROM LOGIN where username =?");
            statement.setString(1, name);
            ResultSet resultset = statement.executeQuery();
            while (resultset.next()) {
                passWord = resultset.getString("PASSWORD");
                userNmae = resultset.getString("USERNAME");
            }

        } catch (Exception e) {
            // TODO: handle exception
        } finally {
            if (connection != null)
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                };
        }

        if (passWord.equalsIgnoreCase(password)) {
            RequestDispatcher rd = request.getRequestDispatcher("welcome.jsp");
            rd.forward(request, response);

        }

    }

    public String getUser() {

        return userNmae;
    }

}

【问题讨论】:

  • 您介意在此处发布您的 jsp 和 servlet 吗?
  • 您究竟是如何从 JSP 调用 getUser() 的?您是否意识到 servlet 的单个实例正在处理来自所有用户的所有请求?当前用户应该存储在 HTTP 会话中,而不是 servlet 中。
  • 这就是我调用方法的方式 ttp://www.w3.org/TR/html4/loose.dtd" rel="nofollow" target="_blank">w3.org/TR/html4/loose.dtd ">

    欢迎

标签: servlets jdbc


【解决方案1】:

我会给你一个更简单的例子来说明你的代码实际上在做什么:

Bottle bottle1 = new Bottle();
bottle1.setMessage("Hi there");

Bottle bottle2 = new Bottle();
System.out.println(bottle2.getMessage());

您希望该程序显示什么?我期待null,因为您在bottle1 上设置了一条消息,并从bottle2 中读取了该消息。这是两个不同的瓶子。当你把信息放在瓶子里时,信息就在那个瓶子里,而不是在其他瓶子里。

你的代码做同样的事情。

  1. servlet 容器创建UIclass 的实例(唯一)。这相当于在我的示例中创建了第一个瓶子。
  2. 发送 HTTP 请求时调用 servlet。它在 servlet 中设置用户属性。在我的示例中,这相当于 bottle1.setMessage("Hi there")
  3. 容器执行你的 JSP,其中包含代码

    <jsp:useBean id="uiclass" class="com.servlet.UIclass" scope="request">
    

    这将创建一个新的 UIClass 实例。相当于在我的示例中创建第二个瓶子。

  4. JSP 调用uiclass.getUser()。这相当于在我的示例中从第二个瓶子中获取消息。

你的代码有很多很多的错误:

  1. 您不应该使用 scriptlet 和 jsp:useBean 标签
  2. 永远不要自己创建 servlet 实例。 servlet 旨在由容器实例化和调用。
  3. 您应该意识到调用了一个唯一的 servlet 实例来同时处理所有用户对该 servlet URL 的所有请求。因此,将用户特定的数据存储在 servlet 属性中是非常错误的
  4. 您可能希望该用户名可用于该用户的所有后续请求。这就是 HTTP 会话的用途。您应该将用户存储为 HTTP 会话的属性:request.getSession().setAttribute("userName", userName)
  5. JSP 应该使用JSP ELJSTL 来访问存储在 servlet 的请求或会话中的 bean:

    <c:out value="${userName}"/>
    

【讨论】:

  • 非常感谢您的帮助 JB Nizet,我正在学习 Jsp 和 servlet,但仍然不知道很多东西。非常感谢您的评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多