java JDBC连接对象在Servlet/Web中返回null

ugmeyewa  于 5个月前  发布在  Java
关注(0)|答案(2)|浏览(51)

我遇到了一个servlet问题--我的数据库连接变成了null。奇怪的是,同样的数据库代码在另一个类中工作得很好。我已经仔细检查了我的配置,加载了JDBC驱动程序,并在Tomcat上测试了它,但是servlet中的连接仍然顽固地为null。

Type Exception Report

Message Cannot invoke "java.sql.Connection.prepareStatement(String)" because "connection" is null

Description The server encountered an unexpected condition that prevented it from fulfilling the request.

Exception

java.lang.NullPointerException: Cannot invoke "java.sql.Connection.prepareStatement(String)" because "connection" is null

字符串
SingletonConnection.java:

public class SingletonConnection {
    private static final String JDBC_URL = "jdbc:mysql://localhost:3306/CATALOGUE";
    private static final String USERNAME = "root";
    private static final String PASSWORD = "";
    private static Connection connection;
    static {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            connection = DriverManager.getConnection(JDBC_URL, USERNAME, PASSWORD);
        } catch (ClassNotFoundException | SQLException e) {
    
            e.printStackTrace();
        }
    }
    public static Connection getConnection() {
        return connection;
    }
}


ProduitdaoImp.java

public class ProduitdaoImp implements IProduitdao {
    @Override
    public List<Produit> chercher(String mc) {
        Connection connection = SingletonConnection.getConnection();
    
        List<Produit> produits = new ArrayList<Produit>();
        try {
    
    PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM PRODUITS                                                                      WHERE DESIGNATION LIKE ?");
            preparedStatement.setString(1, "%" + mc + "%");
            ResultSet rs = preparedStatement.executeQuery();
            while (rs.next()) {
                Produit p = new Produit();
                p.setId(rs.getInt("ID"));
                p.setPrix(rs.getDouble("PRIX"));
                p.setQuantite(rs.getLong("QUANTITE"));
                p.setDesignation(rs.getString("DESIGNATION"));
                produits.add(p);
    
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return produits;
    }  
}


ControleurServlet.java

public class ControleurServlet extends HttpServlet {
    public IProduitdao iProduitdao;
    
    @Override
    public void init() throws ServletException {
        iProduitdao = new ProduitdaoImp();
    }
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws   ServletException, IOException {
        String path = request.getServletPath();
        if (path.equals("/index.do")) {
            request.getRequestDispatcher("Produits.jsp").forward(request, response);
    
        } else if (path.equals("/chercher.do")) {
            String mot = request.getParameter("motcle");
    
            ProduitModel produitModel = new ProduitModel();
    
            produitModel.setMotCle(mot);
    
            List<Produit> produits = iProduitdao.chercher(mot);
            produitModel.setProduits(produits);
            request.setAttribute("model", produitModel);
            request.getRequestDispatcher("Produits.jsp").forward(request, response);
    
        }
    
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    }
}


Produits.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
    <title>Produits</title>
    <link rel="stylesheet" type="text/css" href="css/bootstrap.css">
</head>
<body>
<p></p>
<div>
    <div>
        <div > Recherche des produits</div>
        <div ></div>
        <form method="get" action="chercher.do">
        <label>Mot CLe</label>
            <input type="text" name="motcle"/>

        <button type="submit">Chercher</button>
        </form>
        <table>
            <tr>
            <th>ID</th><th>DESIGNATIONNs</th><th>PRIX</th><th>QUANTITE</th>
            </tr>
            <c:forEach items="${model.produits}" var="p">
                <tr>
                    <td>${p.id}</td>
                    <td>${p.designation}</td>
                    <td>${p.prix}</td>
                    <td>${p.quantite}</td>
                </tr>
            </c:forEach>
        </table>
    </div>
</div>
</body>
</html>

ki1q1bka

ki1q1bka1#

@Basil和其他人给了你很多好建议,如果你听从了,你就不会陷入这种困境。
但到底是什么地方出了问题?
如果您在尝试使用getConnection()返回的连接(假设)时收到NPE:

  • 这意味着private connection字段是null
  • 这意味着static init块没有给connection赋值,
  • 这意味着try... catch中一定抛出并捕获了一个异常,e.printStackTrace()的输出必须转到Tomcat的标准输出。

因此,在服务器日志(包括“ Catalina .out”输出文件)中查找e.printStackTrace()调用的输出。它应该是ClassNotFoundExceptionSQLException的堆栈跟踪。它将在NPE之前发生。该堆栈跟踪将告诉您导致NPE的 * 实际 * 错误。
但是请遵循Basil的建议!还有,log你的异常而不是使用printStackTrace()

j8yoct9x

j8yoct9x2#

数据库连接就像facial tissue..
将您的连接凭据详细信息(如用户名、密码、服务器地址、端口号)存储在DataSource对象中。在应用运行时保持该DataSource对象可用。每次应用需要访问数据库时,请向缓存的DataSource对象请求新连接。
这里是DataSource上的one tutorial。如果你搜索Stack Overflow,你会发现我和其他人的很多例子。看,Why do we use a DataSource instead of a DriverManager?
在学习过程中,您可以硬编码您的连接凭据。在真实的工作中,我们将这些详细信息具体化,以便无需重新编译应用程序即可更改它们。使用JNDI将凭据作为DataSource对象检索。Tomcat具有一个特性,可以以符合JNDI的方式生成DataSource对象。
顺便说一下,Class.forName加载JDBC驱动程序已经不需要很多年了。在现代Java中,JDBC驱动程序通过SPI自动加载。
我怀疑您使用的是过时的、错误的JDBC教程。
要了解更多,search Stack Overflow .你会发现很多信息,包括完整的工作示例应用程序,一些由我创作。
提示:不情愿地使用static。它不是面向对象的。频繁使用可能意味着糟糕的设计。

相关问题