【发布时间】:2021-06-12 15:07:05
【问题描述】:
我目前正在为自己的学习目的开发一个小项目,其中有一个数据库和一个用于访问该数据库的 JSP 页面。我的 Eclipse 上有一个 Java EE 项目,我正在使用以下内容:
- 雄猫 9
- HSQLDB
- Java JDK 15.0.1
- 日食
单独运行下面的 Java 代码时,它可以工作并且我得到了我想要的输出:
shop.RDB
package shop;
import java.sql.*;
import java.util.Collection;
import java.util.LinkedList;
public class RDB
{
private Connection con;
public static void main(String[] args)
{
try
{
RDB test = new RDB();
Collection<Product> ProductsInDB = test.getAllProducts();
for (Product p : ProductsInDB)
{
System.out.println(p.toString());
}
test.shutdown();
}
catch(SQLException e) {e.printStackTrace();}
}
public RDB()
{
try
{
Class.forName("org.hsqldb.jdbc.JDBCDriver");
con = DriverManager.getConnection("jdbc:hsqldb:file:shopDB;hsqldb.lock_file=false", "sa", "");
System.out.println("Created con");
}
catch (Exception e)
{
System.out.println("Exception: " + e);
}
}
public Collection<Product> getAllProducts()
{
return getProductCollection("Select * from Product");
}
public Collection<Product> getProductCollection(String query)
{
LinkedList<Product> list = new LinkedList<Product>();
try {
Statement s = con.createStatement();
ResultSet rs = s.executeQuery(query);
while (rs.next())
{
Product product = new Product(
rs.getString("PID"),
rs.getString("name"),
rs.getDouble("price") );
list.add(product);
}
return list;
}
catch (Exception e)
{
System.out.println("Exception in getProducts(): " + e);
return null;
}
}
public void shutdown() throws SQLException
{
Statement st = con.createStatement();
// db writes out to files and performs clean shuts down
// otherwise there will be an unclean shutdown
// when program ends
st.execute("SHUTDOWN");
con.close(); // if there are no other open connection
}
}
但是,当我尝试做完全相同的事情并在 .jsp 文件中显示数据时,它不起作用:
ProductList.jsp
<%@ page contentType = "text/html;charset=UTF-8" language = "java" %>
<%@ page import = "shop.Product, shop.RDB, java.sql.*, java.util.Collection" %>
<html>
<head> <title>Amazonius Shop</title> </head>
<body>
<h3>Using Database</h3>
<table>
<tr style = "color: red">
<th> ID </th> <th> Product </th> <th> Price </th>
</tr>
<%
try {
RDB DB = new RDB();
Collection<Product> ProductsInDB = DB.getAllProducts();
for (Product p : ProductsInDB)
{
%>
<tr style = "color: blue">
<td> <%= p.PID %> </td>
<td> <%= p.name %> </td>
<td> <%= p.price %> </td>
</tr>
<% }
DB.shutdown();
}
catch(SQLException e) {e.printStackTrace();}
%>
</table>
</body>
</html>
- shop是Java资源文件夹中的包
- Product 是一种自定义数据结构。
- ProductList 是 WebContent 文件夹中的 JSP 文件
并给出此错误:
Mar 15, 2021 10:22:36 AM org.hsqldb.persist.Logger logInfoEvent
INFO: Database closed
Exception: java.sql.SQLException: file input/output error: shopDB.log
Mar 15, 2021 10:22:36 AM org.hsqldb.persist.Logger logSevereEvent
SEVERE: could not reopen database
org.hsqldb.HsqlException: file input/output error: shopDB.log
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.error.Error.error(Unknown Source)
at org.hsqldb.persist.Log.openLog(Unknown Source)
at org.hsqldb.persist.Log.open(Unknown Source)
at org.hsqldb.persist.Logger.open(Unknown Source)
at org.hsqldb.Database.reopen(Unknown Source)
at org.hsqldb.Database.open(Unknown Source)
at org.hsqldb.DatabaseManager.getDatabase(Unknown Source)
at org.hsqldb.DatabaseManager.newSession(Unknown Source)
at org.hsqldb.jdbc.JDBCConnection.<init>(Unknown Source)
at org.hsqldb.jdbc.JDBCDriver.getConnection(Unknown Source)
at org.hsqldb.jdbc.JDBCDriver.connect(Unknown Source)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:677)
at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:228)
at shop.RDB.<init>(RDB.java:32)
at org.apache.jsp.lab6web.ProductList_jsp._jspService(ProductList_jsp.java:183)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:71)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:467)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:378)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:326)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
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:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
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:346)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:887)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1684)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:832)
Exception in getProducts(): java.lang.NullPointerException: Cannot invoke "java.sql.Connection.createStatement()" because "this.con" is null
Mar 15, 2021 10:22:36 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [jsp] in context with path [/Education_Tests_Project] threw exception [An exception occurred processing [lab6web/ProductList.jsp] at line [50]
47: RDB DB = new RDB();
48: Collection<Product> ProductsInDB = DB.getAllProducts();
49:
50: for (Product p : ProductsInDB)
51: {
52: %>
53: <tr style = "color: blue">
Stacktrace:] with root cause
java.lang.NullPointerException: Cannot invoke "java.util.Collection.iterator()" because "ProductsInDB" is null
at org.apache.jsp.lab6web.ProductList_jsp._jspService(ProductList_jsp.java:186)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:71)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:467)
at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:378)
at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:326)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
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:202)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
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:346)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:887)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1684)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:832)
服务器可以很好地处理其他类型的 JSP 代码。此外,我在 Tomcat 的 lib 文件夹中有我的 hsqldb.jar(从教程中看到),并且 Tomcat 在 Java 构建路径中。我已经尝试了几种方法;
- 将 .jar 文件放入 Java 构建路径
- 将 .jar 分别和同时放入 Java bin 和 lib 文件夹中
- 将 .jar 放入 WEB-INF lib 文件夹(从网站上看到)
而且每次尝试都会出现同样的错误。
其他信息
shop.Product
package shop;
public class Product
{
public String PID;
public String name;
public double price;
public Product(String PID, String name, double price)
{
this.PID = PID;
this.name = name;
this.price = price;
}
public String toString()
{
return name + "\t " + price;
}
}
Java 构建路径
【问题讨论】:
-
鉴于错误
org.hsqldb.HsqlException: file input/output error: shopDB.log,我猜是创建或读取数据库有问题,可能是权限问题。顺便说一句,不要捕获异常并继续,就好像什么都没发生一样;在这种情况下会导致次要NullPointerException。
标签: java jsp tomcat jdbc hsqldb