H2 数据库 Java Servlet 连接路径问题

Posted

技术标签:

【中文标题】H2 数据库 Java Servlet 连接路径问题【英文标题】:H2 Database Java Servlet Connection Path issue 【发布时间】:2013-11-05 10:36:16 【问题描述】:

最近我一直在寻找一个带有本地数据库的 servlet。通过一些研究,我发现了H2 Database Engine (Wikipedia)。这非常适合我想要的,但是我的 servlet 的本地路径有问题。

例子:

我需要在我的 WebContent 文件夹中创建 H2 数据库,使其成为项目的一部分。但是我似乎无法正确地对代码进行本地化。

示例代码:- H2.Jar - SQL 数据库的连接字符串

             String url = "jdbc:h2:"+request.getContextPath()+"/emailDB;IFEXISTS=TRUE";
         Class.forName("org.h2.Driver");
            Connection conn = DriverManager.
                getConnection(url, "adminuser", "pass");

示例代码(错误):- H2.Jar - SQL 数据库的连接字符串(输出)

org.h2.jdbc.JdbcSQLException: Database "C:/emailservlet/emailDB" not found [90013-174]
at org.h2.message.DbException.getJdbcSQLException(DbException.java:332)
at org.h2.message.DbException.get(DbException.java:172)
at org.h2.message.DbException.get(DbException.java:149)
at org.h2.engine.Engine.openSession(Engine.java:54)
at org.h2.engine.Engine.openSession(Engine.java:160)
at org.h2.engine.Engine.createSessionAndValidate(Engine.java:139)
at org.h2.engine.Engine.createSession(Engine.java:122)
at org.h2.engine.Engine.createSession(Engine.java:28)
at org.h2.engine.SessionRemote.connectEmbeddedOrServer(SessionRemote.java:323)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:105)
at org.h2.jdbc.JdbcConnection.<init>(JdbcConnection.java:90)
at org.h2.Driver.connect(Driver.java:73)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at emailservlet.msdbcon(emailservlet.java:540)

正如您所看到的,我遇到的问题是,即使我请求上下文路径,我仍然得到 C:/ 之前编写的。

如果您能帮我找出代码中的错误,那将非常有帮助!

提前谢谢你!

【问题讨论】:

getContextPath() 没有返回正确的文件系统路径;它返回 webapp URL 上下文路径。可能是 H2 本身将您提供的相对路径转换为绝对路径。 驱动程序需要它可以创建文件的文件系统路径。它使用 C: 驱动器的根目录将相对路径转换为绝对路径 啊,我不确定如何阻止 H2 更改 url。因为该文件应该可以通过 web url contextpath/file 访问。我已经多次将 requestcontextpath 用于其他应用程序,但我相信您对 H2 的建议是正确的。任何想法如何绕过它设置绝对路径? 【参考方案1】:

驱动程序需要它可以创建文件的文件系统路径。它使用 C: 驱动器的根目录将相对路径转换为绝对路径。要获取 WebContent 文件夹的绝对路径,您需要使用 ServletContext#getRealPath()

另外,将 H2 文件存储在 WebContent 文件夹中也不是一个好主意,您应该将它们存储在 WEB-INF 文件夹中,以便用户无法访问。

下面是url的形成方式

String path = getServletContext().getRealPath("/") + "/WEB-INF";
String url = "jdbc:h2:"+path+"/emailDB;IFEXISTS=TRUE";

这将在 WEB-INF 文件夹中创建 H2 文件。

注意事项来自 H2Database.com 网站上的 Features page:

用于连接到本地数据库的数据库 URL 是 jdbc:h2:[file:][] 。 前缀文件:是可选的。如果不使用或仅使用相对路径,则以当前工作目录为起点。 路径和数据库名称是否区分大小写取决于操作系统,但建议仅使用小写字母。 数据库名称的长度必须至少为三个字符(File.createTempFile 的限制)。 数据库名称不能包含分号。 要指向用户主目录,请使用 ~/,如:jdbc:h2:~/test。

【讨论】:

感谢您的更新。是的,出于这个原因,会把它放在 WEB-INF 中。尝试使用真实路径的建议,我得到 C:/Users/user/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/emailservlet/emailDB 仍在查看驱动器.问题是应用程序需要在系统之间传输,这不起作用:(。 你得到的路径是因为你从 Eclipse 内部运行 tomcat。关于路径,H2 数据库需要绝对路径,但您没有提供绝对路径,而是使用 getRealPath 方法,它应该在任何系统上自动获取正确的绝对路径 好吧,对我来说太简单了!, String url = "jdbc:h2:file:emailDB;IFEXISTS=TRUE"; (文件是 emailDB)这是我的 servlet 的本地文件。返回的错误是:找不到数据库“C:/Program Files (x86)/eclipse/emailDB”[90013-174] - (在我的 eclipse 开发套件中查找该文件)。顺便感谢您一直以来的帮助! 如果您阅读上面 H2 的摘录,前缀文件是可选的。现在您只需提供文件名,即 emailDB,因此它使用当前目录,即 eclipse 文件夹。在tomcat中部署war文件并尝试从eclipse外部运行它你会得到不同的路径 嗨,不幸的是我没有办法在另一个 tomcat 服务器 atm 上运行战争 :( 只能通过 eclipse 在本地运行。我尝试了你的建议 String path / String URl (From Above) 但显然来自在 Eclipse 中我遇到同样的问题“C:/Users/user/workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/emailservlet/WEB-INF/emailDB”找不到 [90013- 174]. (提醒 - 未找到的错误不是问题 - 只是文件路径)

以上是关于H2 数据库 Java Servlet 连接路径问题的主要内容,如果未能解决你的问题,请参考以下文章

Java连接数据库

在 Servlet 和 JDBC 中为 JUnit 分离 H2 数据库 [关闭]

如何从 Java 代码(JSP/Servlet)中停止另一个 tomcat

H2 UDF 类路径

stop tomcat web application 优雅地关闭所有 servlet 连接

尝试连接时未找到 H2 驱动程序