为什么我得到NullPointerException错误?
我试图找出什么是我的错误,但我找不到任何与我的代码被称为空指针。为什么我得到NullPointerException错误?
这里是堆栈跟踪(1):
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1678)
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1523)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:186)
at daftoor.Database.connect(Database.java:92)
at daftoor.DoSignIn.checkSignin(DoSignIn.java:86)
at daftoor.DoSignIn.processRequest(DoSignIn.java:40)
at daftoor.DoSignIn.doGet(DoSignIn.java:122)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:964)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
这里是堆栈跟踪日志(2):
Jul 31, 2012 4:07:41 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [DoSignIn] in context with path [/Daftoor] threw exception
java.lang.NullPointerException
at daftoor.Database.createStatement(Database.java:105)
at daftoor.DoSignIn.checkSignin(DoSignIn.java:91)
at daftoor.DoSignIn.processRequest(DoSignIn.java:40)
at daftoor.DoSignIn.doGet(DoSignIn.java:122)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:405)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:964)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:515)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:302)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
以下是错误页面:
HTTP Status 500 -
type Exception report
message
description The server encountered an internal error() that prevented it from fulfilling this request.
exception
java.lang.NullPointerException
myproject.Database.createStatement(Database.java:101)
myproject.DoSignIn.checkSignin(DoSignIn.java:91)
myproject.DoSignIn.processRequest(DoSignIn.java:40)
myproject.DoSignIn.doGet(DoSignIn.java:127)
javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)
note The full stack trace of the root cause is available in the Apache Tomcat/7.0.22 logs.
Apache Tomcat/7.0.22
以下是我的代码:
数据库类:
package somePackage;
import java.io.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Properties;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author mih1406
*/
public class Database {
private HashMap dbConfig;
private Connection dbConnection;
// debugging
HttpServletRequest request;
HttpServletResponse response;
public Database(HttpServletRequest request, HttpServletResponse respnse) {
this.request = request;
this.response = response;
setDatabaseConfig();
}
public void setDatabaseConfig() {
Properties config = new Properties();
InputStream configFile;
try {
configFile = this.getClass().getResourceAsStream("config.properties");
config.load(configFile);
} catch(FileNotFoundException fnfe) {
// TODO properties file not found error
} catch(IOException ioe) {
// TODO i/o Exception
}
String dbHost = config.getProperty("dbHost");
String dbPort = config.getProperty("dbPort");
String dbUsername = config.getProperty("dbUsername");
String dbPassword = config.getProperty("dbPassword");
String dbName = config.getProperty("dbName");
String dbPrefix = config.getProperty("dbPrefix");
setDatabaseConfig(dbHost, dbPort, dbUsername, dbPassword,
dbName, dbPrefix);
}
public void setDatabaseConfig(String dbHost, String dbPort, String dbUsername,
String dbPassword, String dbName, String dbPrefix) {
dbConfig = new HashMap();
dbConfig.put("dbHost", dbHost);
dbConfig.put("dbPort", dbPort);
dbConfig.put("dbUsername", dbUsername);
dbConfig.put("dbPassword", dbPassword);
dbConfig.put("dbName", dbName);
dbConfig.put("dbPrefix", dbPrefix);
}
public void connect() {
String dbHost = (String)dbConfig.get("dbHost") + "/";
String dbPort = (String)dbConfig.get("dbPort");
String dbUsername = (String)dbConfig.get("dbUsername");
String dbPassword = (String)dbConfig.get("dbPassword");
String dbName = (String)dbConfig.get("dbName");
String dbPrefix = (String)dbConfig.get("dbPrefix");
String dbDriver = "com.mysql.jdbc.Driver";
String dbURL = "jdbc:mysql://" + dbHost + ":" + dbPort + "/";
try {
Class.forName(dbDriver);
dbConnection = DriverManager.getConnection(dbURL, dbURL, dbPassword);
} catch (ClassNotFoundException cnfe) {
// TODO Class Exception
} catch (SQLException sqle) {
// TODO SQL Exception
}
}
public Statement createStatement() {
try {
return dbConnection.createStatement();
} catch(SQLException sqle) {
// TODO SQL Exception
}
return null;
}
public PreparedStatement prepareStatement(String sql) {
PreparedStatement pstmt = null;
try {
pstmt = dbConnection.prepareStatement(sql);
} catch(SQLException sqle) {
// TODO SQL Exception
}
return pstmt;
}
public void close() {
try {
if(dbConnection.isClosed()) {
return;
}
dbConnection.close();
} catch(SQLException sqle) {
// TODO SQL Exception
}
}
public String getPrefix() {
return (String)dbConfig.get("dbPrefix");
}
public String getName() {
return (String)dbConfig.get("dbName");
}
public String getHost() {
return (String)dbConfig.get("dbHost");
}
public String getPort() {
return (String)dbConfig.get("dbPort");
}
public String getUsername() {
return (String)dbConfig.get("dbUsername");
}
public String getPassword() {
return (String)dbConfig.get("dbPassword");
}
}
DoSingin类:
package somePackage;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
*
* @author mih1406
*/
@WebServlet(name = "DoSignIn", urlPatterns = {"/DoSignIn"})
public class DoSignIn extends HttpServlet {
/**
* Processes requests for both HTTP
* <code>GET</code> and
* <code>POST</code> methods.
*
* @param request servlet request
* @param response servlet response
* @throws ServletException if a servlet-specific error occurs
* @throws IOException if an I/O error occurs
*/
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
checkValues(request, response);
checkSignin(request, response);
}
private void checkValues(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String adminUsername = request.getParameter("adminUsername");
String adminPassword = request.getParameter("adminPassword");
boolean someEmpty = false;
if((adminUsername.equals("") || adminUsername == null)) {
someEmpty = true;
request.setAttribute("emptyEmail", "Required");
} else {
request.setAttribute("adminUsername",
request.getParameter("adminUsername"));
}
if((adminPassword.equals("") || adminPassword == null)) {
someEmpty = true;
request.setAttribute("emptyPassword", "Required");
}
if(someEmpty) {
String url = "signin.jsp";
forwardToPage(request, response, url);
}
}
private void forwardToPage(HttpServletRequest request,
HttpServletResponse response, String url)
throws ServletException, IOException {
RequestDispatcher dispatcher = request.getRequestDispatcher(url);
dispatcher.forward(request, response);
}
private void checkSignin(HttpServletRequest request, HttpServletResponse response)
throws ServletException,IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String adminUsername = request.getParameter("adminUsername");
String adminPassword = request.getParameter("adminPassword");
out.println("<br />HereDBCreation!!");
Database db = new Database(request, response);
db.connect();
out.println("<br />HereDBConnectionDone!!");
String query = "SELECT adminUsername, adminPassword FROM " +
db.getPrefix() + db.getName() + " WHERE adminUsername = '" +
adminUsername + "' AND adminPassword = '" + adminPassword + "'";
Statement stmt = db.createStatement();
ResultSet result = null;
if(stmt == null) out.println("<br />HereDBStmtDone!!");
try {
result = stmt.executeQuery(query);
result.beforeFirst();
out.println("Here!!");
if(result.next()){
HttpSession session = request.getSession(true);
session.setMaxInactiveInterval(21*60); // 21 minutes
session.setAttribute("JSESSIONID", adminUsername);
out.println("Correct!!");
} else {
out.println("Invalid!!");
}
} catch(SQLException sqle) {
// TODO SQL Exception
System.out.println(sqle.getMessage());
}
}
}
的signin.jsp JSP文件:
<%--
Document : login
Created on : Jul 19, 2012, 3:36:48 PM
Author : mih1406
--%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Administration</title>
</head>
<body>
<form action="DoSignIn" method="get" name="adminSignInForm">
<table>
<tr>
<td colspan="2">Administration<td>
<br />
</tr>
<tr>
<td><label for="adminUsername">Email:</label></td>
<td><input type="text" value="${adminUsername}" name="adminUsername" />${emptyEmail}</td>
</tr>
<tr>
<td><label for="adminPassword">Password:</label></td>
<td><input type="password" value="" name="adminPassword" />${emptyPassword}</td>
</tr>
<tr>
<td colspan="2">
<input type="checkbox" value="yes" checked="checked" name="persistentCookie" />
<label for="persistentCookie">Stay signed in</label>
</td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="Sign in" /></td>
</tr>
</table>
</form>
</body>
</html>
的问题是在Database.createStatement()
,线:
return dbConnection.createStatement();
引发错误,这意味着dbConnection
为空。
在你connect()
方法你有这些行:
try {
Class.forName(dbDriver);
dbConnection = DriverManager.getConnection(dbURL, dbURL, dbPassword);
} catch (ClassNotFoundException cnfe) {
// TODO Class Exception
} catch (SQLException sqle) {
// TODO SQL Exception
}
所以,即使连接失败,你不会知道它,因为你没有在catch块。
我建议你将其更改为:
try {
Class.forName(dbDriver);
dbConnection = DriverManager.getConnection(dbURL, dbURL, dbPassword);
} catch (ClassNotFoundException cnfe) {
cnfe.printStacktrace();
} catch (SQLException sqle) {
sqle.printStacktrace();
}
,我打赌你会发现,你有一个问题存在。
如果我确实在哪里打印日志? – malhobayyeb 2012-07-31 12:47:27
没有打印日志,它会把它扔到屏幕上。 – Tomer 2012-07-31 12:48:13
@ MIH1406控制台。 – 2012-07-31 12:48:19
正是这些检查
(adminUsername.equals("") || adminUsername == null)
你输入就可以派上作为空值, 并且你已经解释了这一点,但是如果确实如此,它将尝试首先执行此声明adminUsername.equals("")
并抛出NPE。简单地颠倒他们的顺序,它应该可以解决你的问题。
(adminUsername == null || adminUsername.equals(""))
@ ftom2也是正确的,也可能是dbConnection.createStatement();
线,但同出一堆栈跟踪,我们真的不能告诉。您应该进行这些更改以适应null的可能性,以便稍后不会出现问题。
我做到了,但现在使用。 – malhobayyeb 2012-07-31 12:38:13
或“”.equals(admin用户名) – Woot4Moo 2012-07-31 12:39:57
如果你得到一个NullPointerException,你也得到一个堆栈跟踪。堆栈跟踪的第一行显示出错的地方。 – 2012-07-31 12:32:31
我很确定'dbConnection'为空。 – Paranaix 2012-07-31 12:33:11
我在哪里可以看到堆栈跟踪? – malhobayyeb 2012-07-31 12:35:16