2013-05-31 128 views
0

有没有人请赐教,为什么准备语句返回null?下面是查询数据库的代码:这里JDBC PreparedStatement抛出NullPointerException

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; 
} 
} 

然后是调用查询代码:

<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 = "#[email protected]#";  
     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"); } 

当我打电话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) 
+1

这是线61?另外,JSP并不需要理解问题(恕我直言) – SJuan76

+0

第61行是get_user_info方法中finally块中的rset.close()。 – tonix15

回答

1

您发布的东西太多了。

所有你需要的是这样的:

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

在文本编辑器打开ConnectToDB.java,得到了61行,并检查在该行的所有对象的引用。其中之一为空,因为您没有正确初始化它,或者假设它在获得它时总是非空。找出哪一个并正确地初始化它。问题解决了。

我不认为这是一个好的解决方案。如果你有JSP,你有一个servlet/JSP引擎,它应该有一个JNDI数据库连接池和命名服务。您应该设置并将数据库连接参数外部化。他们不属于你的代码。游泳池将比您更好地管理连接。

您还没有正确关闭您的资源。它们应该在finally块中以与创建相反的顺序关闭,并包装在单独的try/catch块中。我会写一个可以调用的静态实用程序方法。

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 
     } 
    } 
} 
+0

所以你说我会改变我的数据库连接到一个池连接?喜欢这个? [Pooled Connection](http://dev.mysql.com/doc/refman/5.1/en/connector-j-usagenotes-j2ee-concepts-connection-pooling.html) – tonix15

+0

你可能会那样做,但这不是你的直接问题。 – duffymo

+1

如果您使用Java 7,请使用try-with-resources,作为求解器说。如果您使用Java 6或更低版本,请保存一些代码并使用commons-db的'DbUtils.closeQuietly()'方法。另外,即使加密,看起来您仍将密码存储在数据库中。这使您的应用程序易受字典攻击。大多数用户选择糟糕的密码,如“密码”,攻击者可以使用它来闯入系统。使用* salting *和* hashing *。安全指南可以解释这些条款。您不想将密码存储在用户对象中。 –

0

您发现的异常是由以前的异常引起的。抛出一个异常在try/catch块的第一行:

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

因此,没有值设置为rsetfinally块之前开始执行,而当你试图用一个空值一种崭新的工作异常。更改您的catch以捕获所有例外情况,您将找到根本原因。

过程中,然后在一个finallycatch块做工作的时候,记住,如果异常被抛出,则不能在try块中的所有代码将被执行,所以也许一些变量没有定义。

请注意,如果您使用的是Java 7,你有可用的try with resourceshttp://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

此外,Exception thrown in catch and finally clause

+0

[executeQuery()](http://docs.oracle.com/javase/1.4.2/docs/api/java/sql/PreparedStatement.html#executeUpdate())根据此api executeQuery()必须插入更新或删除,我使用select查询,这就是为什么它返回null? – tonix15

相关问题