Java - 使用JSch对mysqldatabase进行ssh-tunneling

时间:2015-05-06 06:16:27

标签: java mysql ssh jsch

我已经尝试通过Google和Stackoverflow搜索解决方案。关于这一点有很多话题,但是没有任何帮助我。

function connectorsToString(data) {
        var list = data.company_connector_id;
        var result = "";
        for (var i = 0; i < list.length; i++) {
            result += list[i].Name + ';'; 
        }
        return result;
    }

代码应该做什么:
您应该能够创建GTEVDatabaseConnection的对象。构造函数的参数是ssh-login的用户名和密码。您需要此登录才能连接到我的MySql数据库,因为您只能通过ssh到达它。
因此,当创建一个新对象时,它会通过jsch.getSession(..)创建一个新的Session,并将PortForwarding连接并设置为localhost。 当我尝试执行DriverManager.getConnection(...)时发生错误。 这是错误:

感谢您的帮助。当我遗漏某些东西时询问更多细节。 问候跟踪器

1 个答案:

答案 0 :(得分:1)

我发现了错误。服务器的防火墙阻止了ssh-tunneling。所以我创建了以下代码,它可以工作。

package connection;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelExec;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.logging.Level;
import java.util.logging.Logger;

public class GTEVDatabaseConnection {

private final Channel channel;
private static final int SSH_PORT = 22;
private static final String DATABASE = "databasename",
        DATABASE_USER = "databaseuser",
        DATABASE_PASSWORD = "databasepasswd",
        DATABASE_HOST = "databasehost",
        SSH_HOST = "sshhost";

public GTEVDatabaseConnection(String sshUsername, String sshPassword) {
    try {
        Session sshSession = createSshSession(sshUsername, sshPassword);
        this.channel = sshSession.openChannel("exec");
        ((ChannelExec) channel).setErrStream(System.err);
    } catch (JSchException ex) {
        Logger.getLogger(GTEVDatabaseConnection.class.getName()).log(Level.SEVERE, null, ex);
        throw new SQLException("username or password didn´t work");
    }
}

/**
 * F&uuml;hrt eine SQL-Abfrage aus und liefert eine Tabelle der Ergebnisse
 * @param query Der SQL-Code
 * @return Tabelle der Ergebnisse. Erste Dimension = Zeile; zweite Dimension = Spalte
 * @throws SQLException Tritt auf, wenn der SQL-Befehl eine Fehler ausl&ouml;ste. (Fehler wird per System.err.println(...) ausgegeben)
 */
public ArrayList<ArrayList<String>> execQuery(String query) throws SQLException {
    ArrayList<ArrayList<String>> formattedResult = null;
    try {
        ((ChannelExec) channel).setCommand("mysql -u" + DATABASE_USER + " -p" + DATABASE_PASSWORD + " -h" + DATABASE_HOST + " -e'" + query + "' " + DATABASE);
        InputStream in = channel.getInputStream();
        channel.connect();
        //TODO check whether sqlcode is correct

        String result = readResult(in);
        if(result == null){
            throw new SQLException("Invalid SQL-Code");
        }
        formattedResult = new ArrayList<>();
        for(String row: result.split("\n")){
            ArrayList<String> fields = new ArrayList<>();
            fields.addAll(Arrays.asList(row.split("\t")));
            formattedResult.add(fields);
        }

        channel.disconnect();
    } catch (JSchException | IOException ex) {
        Logger.getLogger(GTEVDatabaseConnection.class.getName()).log(Level.SEVERE, null, ex);
    }

    return formattedResult;
}

private String readResult(InputStream in) throws IOException {
    if (in.available() <= 0) {
        return null;
    }

    StringBuilder output = new StringBuilder();
    int nextByte;
    do {
        nextByte = in.read();
        output.append((char) nextByte);
    } while (nextByte != -1);

    return output.toString();
}

private Session createSshSession(String sshUsername, String sshPassword) throws JSchException {
    Session session = new JSch().getSession(sshUsername, SSH_HOST, SSH_PORT);
    session.setPassword(sshPassword);
    session.setConfig("StrictHostKeyChecking", "no");
    session.connect();
    return session;
}
}

现在程序通过ssh连接,执行mysql命令并读出结果。

它可能不那么专业或“好”,因为我不能使用ResultSet来迭代我的结果,但它可以工作。

我尝试了不同的东西,以便通过telnet连接。

  • 当我没有运行程序时,会出现预期的连接错误。
  • 当我运行程序并暂停它以执行telnet localhost 1234时,cmd被清除且没有响应。
  • 当我尝试输入内容时,再次出现cmd-prompt。所以我只是认为有一个连接......
相关问题