简体   繁体   English

JDBC PreparedStatement抛出NullPointerException

[英]JDBC PreparedStatement throws NullPointerException

Could anybody please enlighten me why prepared statement returns null? 有人可以启发我为什么准备好的语句返回null吗? Here is the code that queries the database: 这是查询数据库的代码:

package beans;
import java.sql.*;
public class ConnectToDB {
private Connection connect;

private final String url = "jdbc:mysql://localhost/";
private final String DBuser = "root";
private final String DBpass = "root";
private final String DBname = "reservation";

private final String Driver = "com.mysql.jdbc.Driver";
public ConnectToDB(){
    try{
        Class.forName(this.Driver);
        this.connect = DriverManager.getConnection(this.url+this.DBname, this.DBuser, this.DBpass);
    }catch(  ClassNotFoundException | SQLException e){ e.printStackTrace(); }
}
public Connection getConnection(){
    return this.connect;
}

private String get_user_info(String username,int index){
    /*
     * user_info[0] = user_id;
     * user_info[1] = username;
     * user_info[2] = password;
     * user_info[3] = firstname;
     * user_info[4] = middle_name;
     * user_info[5] = lastname;
     * user_info[6] = client_rights;
     * 
     */
    String user_info[] = new String[7];
    PreparedStatement pstmt = null;
    ResultSet rset = null;
    String query = null;
    try{
        query = "Select * from user where username = ?";
        pstmt = this.connect.prepareStatement(query);
        pstmt.setString(1, username);
        rset = pstmt.executeQuery();
        while(rset.next()){
            int user_id = rset.getInt("user_id");
            user_info[0] = String.valueOf(user_id);
            user_info[1] = rset.getString("username");
            user_info[2] = rset.getString("password");
            user_info[3] = rset.getString("firstname");
            user_info[4] = rset.getString("middle_name");
            user_info[5] = rset.getString("lastname");
            user_info[6] = rset.getString("user_rights");
        }
    }catch(SQLException e){ e.printStackTrace(); }
    finally{
        try{
            pstmt.close();
            rset.close();
        }catch(SQLException e){ e.printStackTrace(); }
    }
    return user_info[index];
}

public int getUserId(String username){
    String user_id_from_db = get_user_info(username, 0);
    int user_id = Integer.parseInt(user_id_from_db);
    return user_id;
}

public String getUsername(String username){ return get_user_info(username, 1); }
public String getPassword(String username){ return  get_user_info(username, 2); }
public String getFirstname(String username){ return get_user_info(username, 3); }
public String getMiddlename(String username){ return get_user_info(username, 4); }
public String getLastname(String username){ return  get_user_info(username, 5); }
public String getUserRights(String username){ return get_user_info(username, 6); }

public boolean userExists(String username){
    boolean queryStatus = false;
    if(username.equalsIgnoreCase(getUsername(username)))
        queryStatus = true;
    else
        queryStatus = false;
    return queryStatus;
}   
}

Then here is the code that calls the query: 然后是调用查询的代码:

<jsp:useBean id="user" class="beans.ConnectToDB" scope="session" />
<jsp:useBean id="aes" class="beans.AES" scope="session" />

String getUsername = request.getParameter("username");
        String getPassword = request.getParameter("password");  

        final String passphrase = "#asdf@1234#";    
        byte[] password_byte = getPassword.getBytes();  
        byte[] passphrase_byte = passphrase.getBytes();
        byte[] encrypt_password = aes.encrypt(password_byte, passphrase_byte);      

        if((getUsername != null && !getUsername.isEmpty()) || (getPassword != null && !getPassword.isEmpty())){
            String username_from_db = user.getUsername(getUsername);
            String password_from_db = user.getPassword(getUsername);

            byte[] pass_db_byte = password_from_db.getBytes();
            byte[] encrypted_pass_db = aes.encrypt(pass_db_byte, passphrase_byte);

            if(getUsername.equalsIgnoreCase(username_from_db) && encrypt_password.equals(encrypted_pass_db)){
                response.sendRedirect("home_page.jsp");
            }
        }
        else{ response.sendRedirect("index.jsp"); }

When I call getUsername(String username) method it returns null here is the thrown exception: 当我调用getUsername(String username)方法时,它返回null,这是引发的异常:

org.apache.jasper.JasperException: An exception occurred processing JSP page /authenticate_user.jsp at line 29
26:             byte[] encrypt_password = aes.encrypt(password_byte, passphrase_byte);      
27:             
28:             if((getUsername != null && !getUsername.isEmpty()) || (getPassword != null && !getPassword.isEmpty())){
29:                 String username_from_db = user.getUsername(getUsername);
30:                 String password_from_db = user.getPassword(getUsername);
31: 
32:                 byte[] pass_db_byte = password_from_db.getBytes();


Stacktrace:
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:568)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:470)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)

root cause

java.lang.NullPointerException
beans.ConnectToDB.get_user_info(ConnectToDB.java:61)
beans.ConnectToDB.getUsername(ConnectToDB.java:72)
org.apache.jsp.authenticate_005fuser_jsp._jspService(authenticate_005fuser_jsp.java:110)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
javax.servlet.http.HttpServlet.service(HttpServlet.java:728)

You posted too much stuff. 您发布了太多内容。

All you need is this: 您需要的是:

beans.ConnectToDB.get_user_info(ConnectToDB.java:61)

Open up ConnectToDB.java in a text editor, got to line 61, and inspect all the object references on that line. 在文本编辑器中打开ConnectToDB.java,进入第61行,并检查该行上的所有对象引用。 One of them is null because you didn't initialize it properly or assumed that it would always be non-null when you got it. 其中之一为null,因为您未正确对其进行初始化,或者假定当您获取它时它始终为非null。 Figure out which one and initialize it properly. 找出哪一个并正确初始化。 Problem solved. 问题解决了。

I don't think this is a good solution. 我认为这不是一个好的解决方案。 If you have JSPs, you have a servlet/JSP engine, which should have a JNDI database connection pool and naming service. 如果您有JSP,则您有一个Servlet / JSP引擎,该引擎应具有JNDI数据库连接池和命名服务。 You should set that up and externalize your database connection parameters. 您应该进行设置并外部化数据库连接参数。 They don't belong in your code. 它们不属于您的代码。 A pool will manage connections better than you will. 池将比您更好地管理连接。

You aren't closing your resources properly, either. 您也没有正确关闭资源。 They should be closed in a finally block, in reverse order of creation, wrapped in individual try/catch blocks. 它们应按创建的相反顺序在finally块中关闭,并包装在单独的try / catch块中。 I would write a static utility method that could be called to do it. 我会写一个静态实用程序方法来调用它。

package persistence;

public class DatabaseUtils {
    private DatabaseUtils() {}

    // Similar for ResultSet and Connection
    public static void close(Statement st) {
        try {
            if (st != null) {
                st.close();
            }
        } catch (Exception e) {
            // Log the exception
        }
    }
}

The exception you catch is caused by a previously one. 您捕获的异常是由先前的异常引起的。 An exception is thrown in the first lines of the try/catch block: try/catch块的第一行中引发异常:

    pstmt = this.connect.prepareStatement(query);
    pstmt.setString(1, username);
    rset = pstmt.executeQuery();

So no value is set to rset before the finally block begins executing, and a new exception is raised as you try to work with a null value. 因此,在finally块开始执行之前,没有将值设置为rset ,并且在尝试使用null值时会引发新的异常。 Change your catch to capture all exceptions and you will find the root cause. 更改catch以捕获所有异常,您将找到根本原因。

And of course, when doing work with a finally or catch block, mind that if an exception has been thrown then not all code in the try block will have been executed, so maybe some variables are not defined. 当然,在使用finallycatch块进行工作时,请注意,如果引发了异常,则try块中的并非所有代码都会被执行,因此可能未定义某些变量。

Note that if you are using Java 7, you have available the try with resources : http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html 请注意,如果您使用的是Java 7,则可以try with resources进行try with resourceshttp : //docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

Also, Exception thrown in catch and finally clause 另外, 在catch和finally子句中引发异常

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM