【问题标题】:Cannot invoke "java.sql.Connection.close()" because "c" is null [duplicate]无法调用“java.sql.Connection.close()”,因为“c”为空 [重复]
【发布时间】: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,要么将其包装在您自己的异常中以传播错误。

标签: java servlets


【解决方案1】:

在尝试关闭连接之前,请检查该连接不是 null

public void freeConnection(Connection c) {
    if (c == null) {
        return;
    }
    try {
        c.close();
    } catch (SQLException e) {
        System.out.println(e);
    }
}

【讨论】:

  • 但这不会使问题更加复杂吗?在我的情况下,我从 StudentDB.java 程序获得Cannot invoke "java.sql.Connection.prepareStatement(String)" because "connection" is null
  • @RamonZarate 异常来自关闭电话。这将解决这个问题。不会修复您在getConnection() 中未提及的任何错误;但奇怪的是getConnection() 没有调用pool.getConnection()
  • 嗯,那是因为我在其他地方调用了它;在 StudentDB.java 程序中
猜你喜欢
  • 1970-01-01
  • 2022-11-19
  • 2021-12-08
  • 2022-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-18
相关资源
最近更新 更多