1

下午好。我尝试从 eclipse 的 java 代码连接到数据库。我需要发出请求并检查表单中输入的用户名和密码是否相互匹配。用户名及其密码列表位于名为 stud_test 的数据库中。我需要运行 gradle 和 tomcat 来检查 servlet 是否工作。当我这样做并打开所需的页面时,我看到了 PSQLExceptions。我的代码示例如下。我不明白有什么问题。

public void doPost(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException,IOException {

    Connection con;
    ResultSet rs;

    String URL = "jdbc:postgresql://localhost:5432/stud_test";
    String username = request.getParameter("useruser");
    String passwrd = request.getParameter("pass");
    response.setContentType("text/html");

    try {
        con = DriverManager.getConnection(URL, "postgres", "postgres");
        Statement st = con.createStatement();
        st.executeQuery ("SELECT password FROM stud WHERE user = " + username);
        rs = st.getResultSet();

        if (passwrd.equals(rs)){
            request.getServletContext().getRequestDispatcher(
            "/jsp/hello.jsp").forward(request, response);
        }
        else {
            request.getServletContext().getRequestDispatcher("/jsp/fail.jsp").forward(request, response);
        }

        rs.close ();
        st.close ();
    } 

    catch(Exception e) {
        System.out.println("Exception is :" + e);
    }   
}
4

2 回答 2

1

除了 Sergiu 已经提到的之外,以下行不太可能满足您的要求:

st.executeQuery ("SELECT password FROM stud WHERE user = " + username);

例如,如果用户名是“carl”,那么以下语句将被发送到数据库:

SELECT password FROM stud WHERE user = carl

如果没有名为“carl”的列,则会导致语法错误。解决这个问题的“明显”(和错误的方法!)将是使用

st.executeQuery ("SELECT password FROM stud WHERE user = '" + username + "'");

这可能(起初)有效,但会使您容易受到 SQL 注入的攻击。请求信息的正确方法是使用准备好的语句和参数:

final PreparedStatement stm = connection.prepareStatement(
        "SELECT password FROM stud WHERE user = ?");

try {

    // For each "hole" ("?" symbol) in the SQL statement, you have to provide a
    // value before the query can be executed. The holes are numbered from left to
    // right, starting with the left-most one being 1. There are a lot of "setXxx"
    // methods in the prepared statement interface, and which one you need to use
    // depends on the type of the actual parameter value. In this case, we assign a
    // string parameter:

    stm.setString(1, username);

    final ResultSet rs = stm.executeQuery();

    try {

        if (rs.next()) {

            if (password.equals(rs.getString(1))) {

                 // Yay. Passwords match. User may log in

            }
        }

    } finally {

         rs.close();
    }

} finally {

    stm.close();
}

是的,在 Java 中通过 JDBC 与数据库通信需要大量的样板代码。不,“明显”的解决方案是错误的!错误的!错误的!

于 2013-10-23T11:23:54.443 回答
0

I think you should have

if (passwrd.equals(rs.getString(1))){ ... }

assuming the user field is a varchar in the DB.

You can not match a string(passwrd) to a ResultSet instance (rs).

于 2013-10-23T10:58:03.693 回答