使用 SSH java 连接到数据库
connect to DB using SSH java
我尝试在 java 中连接到 Oracle DB,但我遇到了错误,我搜索了很多次都没有找到帮助我的东西。
当我尝试使用 SQL 开发人员进行连接时,它成功了。
所以我尝试编写 java 代码来访问数据库,它成功连接到 SSH,但是当到达 conn = DriverManager.getConnection
:
时我遇到了错误
"java.sql.SQLException: Io exception: Oracle Error ORA-12650"
这是我的功能
public static Connection sshTunel() {
String sshHost = "sshHost";
String sshuser = "sshUser";
String SshKeyFilepath =
"pathOfKey";
Session session;
int localPort = 22;
String remoteHost = "HostIp";
int remotePort = 1521;
String usr = "DB user";
String pwd = "DB pass";
try {
java.util.Properties config = new java.util.Properties();
JSch jsch = new JSch();
session = jsch.getSession(sshuser, sshHost, 22);
jsch.addIdentity(SshKeyFilepath, "ssh Pass");
config.put("StrictHostKeyChecking", "no");
config.put("Compression", "yes");
config.put("ConnectionAttempts", "2");
session.setConfig(config);
session.connect();
System.out.println("SSH Connected ...");
int assinged_port =
session.setPortForwardingL(localPort, remoteHost, remotePort);
System.out.println("localhost:" + assinged_port + " -> " +
remoteHost + ":" + remotePort);
System.out.println("Port Forwarded ...");
try {
Class.forName("oracle.jdbc.pool.OracleDataSource");
conn =
DriverManager.getConnection("jdbc:oracle:thin:@remoteHost:1521/SID",
"DB User", "DB Pass");
} catch (SQLException ex) {
ex.printStackTrace();
System.out.println("Error in connection");
}
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
SSH 连接到端口 22。隧道的本地端口应该是一个不同的非保留端口,例如61521.
然后您使用 SQL*Net URL 中的本地地址和端口进行连接。
所以只显示相关部分:
int localPort = 61521;
String remoteHost = "HostIp";
int remotePort = 1521;
...
try {
java.util.Properties config = new java.util.Properties();
JSch jsch = new JSch();
session = jsch.getSession(sshuser, sshHost, 22);
...
session.setConfig(config);
session.connect();
System.out.println("SSH Connected ...");
int assinged_port =
session.setPortForwardingL(localPort, remoteHost, remotePort);
System.out.println("localhost:" + assinged_port + " -> " +
remoteHost + ":" + remotePort);
try {
Class.forName("oracle.jdbc.pool.OracleDataSource");
conn = DriverManager.getConnection(
"jdbc:oracle:thin:@localhost:61521/service_name",
"DB User", "DB Pass");
} catch (SQLException ex) {
...
在您的 SQL Developer 屏幕截图中,我希望第一个主机值是您的远程主机,即您的代码中实际存在的任何“sshHost”; SSH 在端口 22 上联系。第二个主机和端口值是如何通过 通过 SSH 会话到达数据库侦听器,而不是您。 ('localhost' 有远程服务器;它 将其视为本地主机,并到达环回地址 127.0.0.1)。通过单选按钮选择,SSH 连接正在分配自己的本地端口,并连接到该端口,您真的不需要知道它有什么价值。
在您的代码中,此调用:
jsch.getSession(sshuser, sshHost, 22);
这相当于 SQL 开发人员对话框中的第一个主机和端口。同样,sshHost
是第一个主机框中的值。
然后这个调用:
session.setPortForwardingL(localPort, remoteHost, remotePort);
相当于 SQL 开发人员屏幕截图中的第二个主机和端口部分。这里,remoteHost
是主机值,可能是localhost
; remotePort
为端口值,即1521。
这与 SQL 开发人员设置的不同之处在于 localPort
值。在自动分配的 SQL 开发人员中(因为您选择了 'automatically assign local port')。在您的代码中,您指定的是您自己,并且该值必须是非保留端口。
因此,只需使用相关部分,您就可以执行以下操作:
jsch.getSession(sshuser, 'your_remote_host', 22);
session.connect();
session.setPortForwardingL(61521, 'localhost', 1521);
DriverManager.getConnection(
"jdbc:oracle:thin:@localhost:61521/service_name"
可能有点令人困惑,因为有两个地方提到了 localhost
,而且它们的意思似乎略有不同。那是因为它是保留在计算机中的特殊环回地址(因此 'local')。您可以将第一个(在 setPortForwaringL
中)视为远程服务器对自身的内部引用;第二个(在 getConnection()
中)作为您的 PC 对 自身 .
的内部引用
更令人困惑的是,您的屏幕截图显示了两个主机值的 localhost
。如果那是您真正拥有的,那么它就没有多大意义,您根本不需要 SSH。所以,我想你更改了真实值以隐藏它以供发布,并且只是选择了一个令人困惑的假值,而不是使用 sshHost
或 hostIP
或类似的。
我尝试在 java 中连接到 Oracle DB,但我遇到了错误,我搜索了很多次都没有找到帮助我的东西。
当我尝试使用 SQL 开发人员进行连接时,它成功了。
所以我尝试编写 java 代码来访问数据库,它成功连接到 SSH,但是当到达 conn = DriverManager.getConnection
:
"java.sql.SQLException: Io exception: Oracle Error ORA-12650"
这是我的功能
public static Connection sshTunel() {
String sshHost = "sshHost";
String sshuser = "sshUser";
String SshKeyFilepath =
"pathOfKey";
Session session;
int localPort = 22;
String remoteHost = "HostIp";
int remotePort = 1521;
String usr = "DB user";
String pwd = "DB pass";
try {
java.util.Properties config = new java.util.Properties();
JSch jsch = new JSch();
session = jsch.getSession(sshuser, sshHost, 22);
jsch.addIdentity(SshKeyFilepath, "ssh Pass");
config.put("StrictHostKeyChecking", "no");
config.put("Compression", "yes");
config.put("ConnectionAttempts", "2");
session.setConfig(config);
session.connect();
System.out.println("SSH Connected ...");
int assinged_port =
session.setPortForwardingL(localPort, remoteHost, remotePort);
System.out.println("localhost:" + assinged_port + " -> " +
remoteHost + ":" + remotePort);
System.out.println("Port Forwarded ...");
try {
Class.forName("oracle.jdbc.pool.OracleDataSource");
conn =
DriverManager.getConnection("jdbc:oracle:thin:@remoteHost:1521/SID",
"DB User", "DB Pass");
} catch (SQLException ex) {
ex.printStackTrace();
System.out.println("Error in connection");
}
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
SSH 连接到端口 22。隧道的本地端口应该是一个不同的非保留端口,例如61521.
然后您使用 SQL*Net URL 中的本地地址和端口进行连接。
所以只显示相关部分:
int localPort = 61521;
String remoteHost = "HostIp";
int remotePort = 1521;
...
try {
java.util.Properties config = new java.util.Properties();
JSch jsch = new JSch();
session = jsch.getSession(sshuser, sshHost, 22);
...
session.setConfig(config);
session.connect();
System.out.println("SSH Connected ...");
int assinged_port =
session.setPortForwardingL(localPort, remoteHost, remotePort);
System.out.println("localhost:" + assinged_port + " -> " +
remoteHost + ":" + remotePort);
try {
Class.forName("oracle.jdbc.pool.OracleDataSource");
conn = DriverManager.getConnection(
"jdbc:oracle:thin:@localhost:61521/service_name",
"DB User", "DB Pass");
} catch (SQLException ex) {
...
在您的 SQL Developer 屏幕截图中,我希望第一个主机值是您的远程主机,即您的代码中实际存在的任何“sshHost”; SSH 在端口 22 上联系。第二个主机和端口值是如何通过 通过 SSH 会话到达数据库侦听器,而不是您。 ('localhost' 有远程服务器;它 将其视为本地主机,并到达环回地址 127.0.0.1)。通过单选按钮选择,SSH 连接正在分配自己的本地端口,并连接到该端口,您真的不需要知道它有什么价值。
在您的代码中,此调用:
jsch.getSession(sshuser, sshHost, 22);
这相当于 SQL 开发人员对话框中的第一个主机和端口。同样,sshHost
是第一个主机框中的值。
然后这个调用:
session.setPortForwardingL(localPort, remoteHost, remotePort);
相当于 SQL 开发人员屏幕截图中的第二个主机和端口部分。这里,remoteHost
是主机值,可能是localhost
; remotePort
为端口值,即1521。
这与 SQL 开发人员设置的不同之处在于 localPort
值。在自动分配的 SQL 开发人员中(因为您选择了 'automatically assign local port')。在您的代码中,您指定的是您自己,并且该值必须是非保留端口。
因此,只需使用相关部分,您就可以执行以下操作:
jsch.getSession(sshuser, 'your_remote_host', 22);
session.connect();
session.setPortForwardingL(61521, 'localhost', 1521);
DriverManager.getConnection(
"jdbc:oracle:thin:@localhost:61521/service_name"
可能有点令人困惑,因为有两个地方提到了 localhost
,而且它们的意思似乎略有不同。那是因为它是保留在计算机中的特殊环回地址(因此 'local')。您可以将第一个(在 setPortForwaringL
中)视为远程服务器对自身的内部引用;第二个(在 getConnection()
中)作为您的 PC 对 自身 .
更令人困惑的是,您的屏幕截图显示了两个主机值的 localhost
。如果那是您真正拥有的,那么它就没有多大意义,您根本不需要 SSH。所以,我想你更改了真实值以隐藏它以供发布,并且只是选择了一个令人困惑的假值,而不是使用 sshHost
或 hostIP
或类似的。