问题描述
我目前正在为我自己的学习目的开展一个小项目,其中有一个数据库和一个用于访问该数据库的 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>
并给出此错误:
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 代码。此外,我的 hsqldb.jar 位于 Tomcat 的 lib 文件夹中(从教程中看到),而 Tomcat 位于 Java 构建路径中。我已经尝试了几种方法;
而且每次尝试都会出现相同的错误。
附加信息
商店.产品
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 构建路径
解决方法
您的连接 URL 有问题。在 Tomcat 或其他应用程序服务器上,目录通常是只读的,您无法在那里创建数据库。有关如何指向您的主目录或在 Tomcat 属性中定义为数据目录的目录,请参阅 http://hsqldb.org/doc/2.0/guide/dbproperties-chapt.html#dpc_variables_url。您不应在 URL 上使用 hsqldb.lock_file=false
,因为不建议在正常使用中使用。下面的示例使用主目录作为数据库位置。
con = DriverManager.getConnection("jdbc:hsqldb:file:~/shopDB","sa","");