使用 Java 应用程序远程连接到 H2 数据库
Posted
技术标签:
【中文标题】使用 Java 应用程序远程连接到 H2 数据库【英文标题】:Connect remotely to an H2 Database using a Java Application 【发布时间】:2013-01-11 16:55:26 【问题描述】:我遇到以下问题: 当我尝试使用我的外部 IP 地址(PC 的 IP 而不是我的本地 IP = 我们在 cmd.exe 中运行 ipconfig 后看到的输出)创建 TcpServer 时,会发生以下错误:
服务器错误:异常打开端口“9092”(端口可能正在使用),原因:“java.net.BindException:无法分配请求的地址:JVM_Bind”[90061-169]
但是,该端口未使用。我已经使用 netstat -a -n 进行了检查。 我已启用我的外部 IP,并已禁用路由器的防火墙。我的外部 IP 现在可以被 ping 通了。
请帮帮我。
更新:这是我启动 tcp 服务器的代码。
package businessApp;
import org.h2.tools.Server; //imports the server utility
public class startTcpServerForH2
Server server; //the server's instance variable
private static final String SERVER_IP = "192.168.1.101"; //fixed IP of the server
private static final String SERVER_PORT = "9092"; //fixed port the server is listening to
public void tcpServer() //method responsible to create the tcp server
optionPane optPane = new optionPane(); //option pane for debugging purposes, shows the server's status
try //catches any server related errors, if the connection is broken etc.
//server uses the IP and port defined earlier, allows other computers in the LAN to connect and implements the secure socket layer (SSL) feature
server = Server.createTcpServer( //create tcp server
new String[] "-tcpPort" , SERVER_PORT , "-tcpAllowOthers" , "-tcpSSL" ).start();
System.out.println(server.getStatus()); //prints out the server's status
optPane.checkServerStatus(server.getStatus()); //prints out the server's status on the option pane as well
catch(Exception ex)
System.out.println("Error with Server: " + ex.getMessage());
public static void main(String[] args)
startTcpServerForH2 tcpServ = new startTcpServerForH2(); //create a new server object
tcpServ.tcpServer(); //starts the tcp server
第二次更新:这里是 h2Connection 代码。
打包businessApp;
导入 java.sql.*; //导入sql特征
//负责与H2数据库引擎连接的类 公共类 h2Connection
Connection conn; //connection variable
DatabaseMetaData dbmd; /** Metadata variable which include methods such as the following:
* 1) Database Product Name
* 2) Database Product Version
* 3) URL where the database files are located (in TCP mode)
*/
Statement stm; //statements variable
ResultSet rst; //result sets variable
private static final String SERVER_IP = "..."; //here I enter my WAN_IP
private static final String SERVER_PORT = "9092";
public Connection connectionToH2(Connection connt)
optionPane optPane = new optionPane(); //create new option pane object
String outputConn = null; //declare & initialize string which will hold important messages
try
Class.forName("org.h2.Driver"); //Driver's name
/** The String URL is pertained of the following:
* 1) jdbc which java implements so that it can take advantage of the SQL features
* 2) Which Database Engine will be used
* 3) URL where the files will be stored (as this is a TCP connection)
* 4) Schema: businessApp
* 5) Auto server is true means that other computers can connect with the same databse at any time
* 6) Port number of the server is also defined
*/
String url = "jdbc:h2:tcp://" + SERVER_IP + ":" + SERVER_PORT + "/C:/Databases/businessApp;IFEXISTS=TRUE";
System.out.println(url); //prints out the url the database files are located as well as the h2 features used (SSL)
connt = DriverManager.getConnection(url, "sa", ""); //Driver Manager defines the username & password of the database
System.out.println(connt.getCatalog()); //prints out the database schema
optPane.checkServerStatus(connt.getCatalog()); //prints out the database schema on the option pane as well
connt.setAutoCommit(false); //set AutoCommit to false to control commit actions manually
//outputs H2 version and the URL of the database files which H2 is reading from, for confirmation
dbmd = connt.getMetaData(); //get MetaData to confirm connection
outputConn = "Connection to "+dbmd.getDatabaseProductName()+" "+
dbmd.getDatabaseProductVersion()+ " with the URL " + dbmd.getURL()+" was successful.\n";
System.out.println(outputConn); //outputs the message on the system (NetBeans compiler)
optPane.checkH2Connection(outputConn); //outputs the message on top of the frame
catch (ClassNotFoundException ex) //In case there is an error for creating the class for the Driver to be used
System.out.println("Error creating class: " + ex.getMessage());
catch(SQLException ex) //Any error associated with the Database Engine
System.out.println("SQL error: " + ex.getMessage());
optPane.checkServerStatus("SQL error: " + ex.getMessage());
return connt; //As the method is not void, a connection variable must be returned
当我想连接到 h2 数据库时,我创建了一个新的 h2Connection 对象并使用它来连接。我一个字一个字地跟着 H2 手册。你还需要什么?
【问题讨论】:
【参考方案1】:正如下面显示的命令行帮助中所建议的,Protection against Remote Access 建议如下:
默认情况下,此数据库在启动 H2 控制台、TCP 服务器或 PG 服务器时不允许来自其他机器的连接。可以使用命令行选项
-webAllowOthers
、-tcpAllowOthers
、-pgAllowOthers
启用远程访问。
请参阅有关这些选项的重要 caveats 的文档。
附录:对我有用,只要我重启Server
在打开防火墙后;你根本不需要setProperty()
行;您的WAN_IP
将端口9092 转发到的LAN IP
应该是您的主机IP 地址;然后你可以通过WAN_IP
打开一个shell:
java -cp h2.jar org.h2.tools.Shell -url
jdbc:h2:tcp://WAN_IP/~/path/to/test;ifexists=true"
命令行帮助:
$ java -cp .:/opt/h2/bin/h2.jar org.h2.tools.Shell -? 使用 JDBC 访问数据库的交互式命令行工具。 用法:java org.h2.tools.Shell 选项区分大小写。支持的选项有: [-help] 或 [-?] 打印选项列表 [-url ""] 数据库 URL (jdbc:h2:...) [-user ] 用户名 [-password ] 密码 [-driver ] 要使用的 JDBC 驱动程序类(大多数情况下不需要) [-sql ""] 执行SQL语句并退出 [-properties ""] 从此目录加载服务器属性 如果特殊字符不能按预期工作,您可能需要使用 -Dfile.encoding=UTF-8 (Mac OS X) 或 CP850 (Windows)。 另请参阅 http://h2database.com/javadoc/org/h2/tools/Shell.html $ java -cp /opt/h2/bin/h2.jar org.h2.tools.Server -? 启动 H2 控制台 (web-) 服务器、TCP 和 PG 服务器。 用法:java org.h2.tools.Server 不带选项运行时,会启动 -tcp、-web、-browser 和 -pg。 选项区分大小写。支持的选项有: [-help] 或 [-?] 打印选项列表 [-web] 使用 H2 控制台启动 Web 服务器 [-webAllowOthers] 允许其他计算机连接 - 见下文 [-webDaemon] 使用守护线程 [-webPort ] 端口(默认:8082) [-webSSL] 使用加密 (HTTPS) 连接 [-browser] 启动浏览器连接到网络服务器 [-tcp] 启动 TCP 服务器 [-tcpAllowOthers] 允许其他计算机连接 - 见下文 [-tcpDaemon] 使用守护线程 [-tcpPort ] 端口(默认:9092) [-tcpSSL] 使用加密 (SSL) 连接 [-tcpPassword ] 关闭 TCP 服务器的密码 [-tcpShutdown ""] 停止 TCP 服务器;示例:tcp://localhost [-tcpShutdownForce] 不要等到所有连接都关闭 [-pg] 启动 PG 服务器 [-pgAllowOthers] 允许其他计算机连接 - 见下文 [-pgDaemon] 使用守护线程 [-pgPort ] 端口(默认值:5435) [-properties ""] 服务器属性(默认:~,禁用:null) [-baseDir ] H2 数据库的基本目录(所有服务器) [-ifExists] 只能打开现有数据库(所有服务器) [-trace] 打印附加跟踪信息(所有服务器) 选项 -xAllowOthers 具有潜在风险。 有关详细信息,请参阅高级主题/防止远程访问。 另请参阅 http://h2database.com/javadoc/org/h2/tools/Server.html【讨论】:
请检查我上面更新的问题,我已经包含了启动 tcp 服务器的代码。我的问题是我无法将我的外部 IP 与服务器绑定以进行远程访问。也许我做错了。使用我的内部 IP,一切正常,但仅适用于连接到我的 LAN 的计算机。 我不确定您是否需要h2.bindAddress
。你的边界路由器转发9092
吗?
我的路由器是基于3G移动宽带技术的。在其设置下,我创建了一个新的虚拟服务器,其 LAN IP 地址为 192.168.1.101,LAN 和 WAN 端口都输入为“9092”。然后我将上面的 SERVER_IP 更改为我的外部 IP 并运行代码。我还关闭了路由器上的防火墙设置。还是不行。
感谢您的帮助。我只有最后一个问题:我已经在我的电脑上尝试了你上面所说的,但它没有用!你在你的电脑上试过吗?可以同时做服务端和客户端连接广域网IP吗?
两者都同意;这是example。使用netstat
验证您的服务器是否正在侦听端口 9092;在 URL 中使用localhost
来验证您是否可以连接到它;然后使用您的外部 IP 地址。以上是关于使用 Java 应用程序远程连接到 H2 数据库的主要内容,如果未能解决你的问题,请参考以下文章