【发布时间】:2022-01-10 00:57:59
【问题描述】:
我正在尝试在我的 Java Servlet 项目中创建一个连接池。我的代码如下:
ConnectionPool.java
package dbconn;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class ConnectionPool {
private static ConnectionPool pool = null;
private static DataSource dataSource = null;
private ConnectionPool() {
try {
InitialContext ic = new InitialContext();
dataSource = (DataSource) ic.lookup("java:/comp/env/jdbc/ita2");
} catch (NamingException e) {
System.out.println(e);
}
}
public static synchronized ConnectionPool getInstance() {
if (pool == null) {
pool = new ConnectionPool();
}
return pool;
}
public Connection getConnection() {
Connection con = null;
String dbName = "ita2";
String userName = "root";
String password = "";
String hostname = "localhost";
String port = "3306";
String jdbcUrl = "jdbc:mysql://" + hostname + ":" + port + "/" + dbName + "?user=" + userName+ "&password=" + password;
try
{
try
{
Class.forName("com.mysql.jdbc.Driver");
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
con = DriverManager.getConnection(jdbcUrl);
System.out.println("Post establishing a DB connection - "+con);
}
catch (Exception e){
e.printStackTrace();
}
return con;
}
public void freeConnection(Connection c) {
try {
c.close();
} catch (SQLException e) {
System.out.println(e);
}
}
}
StudentDB.java
public class StudentDB {
public static int insert(Student user) {
ConnectionPool pool = ConnectionPool.getInstance();
Connection connection = pool.getConnection();
PreparedStatement ps = null;
String query
= "INSERT INTO Student (id, fname, lname, uname, email, password, salt) "
+ "VALUES (?, ?, ?, ?, ?, ?,?)";
try {
ps = connection.prepareStatement(query);
ps.setString(1, user.getSid());
ps.setString(2, user.getFirstName());
ps.setString(3, user.getLastName());
ps.setString(4, user.getUsername());
ps.setString(5, user.getEmail());
ps.setString(6, user.getPassword());
ps.setString(7,user.getSalt());
return ps.executeUpdate();
} catch (SQLException e) {
System.out.println(e);
return 0;
} finally {
DBUtil.closePreparedStatement(ps);
pool.freeConnection(connection);
}
}
}
StudentRegister.java
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
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;
@WebServlet("/StudentRegister")
public class StudentRegister extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String url = "/index.html";
// get current action
String action = request.getParameter("action");
if (action == null) {
action = "join"; // default action
}
// perform action and set URL to appropriate page
if (action.equals("join")) {
url = "/index.jsp"; // the "join" page
}
else if (action.equals("add")) {
// get parameters from the request
String firstName = request.getParameter("firstname");
String lastName = request.getParameter("lastname");
String username = request.getParameter("username");
String password = request.getParameter("password");
String email = request.getParameter("email");
String sid = request.getParameter("sid");
HttpSession session = request.getSession(true);
session.setAttribute("studentid",sid);
System.out.println("student id is "+ session.getAttribute("studentid"));
// check strength requirements
String message1;
try {
PasswordUtil.checkPasswordStrength(password);
message1 = "";
} catch (Exception e) {
message1 = e.getMessage();
}
request.setAttribute("message", message1);
// hash and salt password
String hashedPassword;
String salt = "";
String saltedAndHashedPassword;
try {
hashedPassword = PasswordUtil.hashPassword(password);
salt = PasswordUtil.getSalt();
saltedAndHashedPassword = PasswordUtil.hashAndSaltPassword(password);
} catch (NoSuchAlgorithmException ex) {
hashedPassword = ex.getMessage();
saltedAndHashedPassword = ex.getMessage();
}
request.setAttribute("HashedPassword", hashedPassword);
request.setAttribute("Salt", salt);
request.setAttribute("SaltedAndHashedPassword", saltedAndHashedPassword);
// store data in User object
Student user = new Student(sid, username, saltedAndHashedPassword, firstName, lastName, email,salt);
System.out.println("Salt before saving " + user);
// validate the parameters
String message;
{ message = "";
url = "/thanks.jsp";
StudentDB.insert(user);
}
request.setAttribute("user", user);
request.setAttribute("message", message);
}
getServletContext()
.getRequestDispatcher(url)
.forward(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
}
}
在运行 StudentRegister servlet 时,我遇到了上面标题中给出的错误,这与 ConnectionPool.java 程序中的 freeConnection() 方法有关。是因为查找失败/查找链接不存在吗?应该注意的是,我正在使用本地 WAMP 服务器来实现我的目的。任何帮助将不胜感激!
编辑
这是整个堆栈跟踪:
java.lang.NullPointerException: Cannot invoke "java.sql.Connection.prepareStatement(String)" because "connection" is null
at dbconn.StudentDB.insert(StudentDB.java:18)
at student.StudentRegister.doPost(StudentRegister.java:83)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:382)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:895)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1722)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:831)
【问题讨论】:
-
你能分享堆栈跟踪吗?您的应用程序中应该有更多日志。原因可能不同。我看到很多让应用程序继续运行的“异常情况”。
-
堆栈跟踪与帖子的标题不匹配 - 尽管您可能会同时获得两者(因为
finally)。ConnectionPool.getConnection()的实现可以返回被StudentDB忽略的null。查看日志以获取更多信息... -
我希望在 DriverManager.getConnection(jdbcUrl) 处至少有一个“抑制”异常,您可以在其中打印堆栈跟踪。建议你看看stackoverflow.com/questions/2839321/…
-
不要使用此类方法关闭资源,使用try-with-resources。此外,您的
getConnection()方法存在根本缺陷,因为它在创建连接时发生异常时返回null。不要返回 null,要么直接抛出SQLException,要么将其包装在您自己的异常中以传播错误。