java这边没有很好的封装工具连接ssh,jsch使用起来只是略微方便一点,使用的时候可以封装成工具自己使用
jsch有2种方式和客户端进行交互==ChannelShell和ChannelExec
ChannelShell和ChannelExec区别?
参考:https://blog.youkuaiyun.com/u013066244/article/details/70911585
ChannelShell
对于ChannelShell,以输入流的形式,提供命令和输入这些命令,这就像在本地计算机上使用交互式shell(它通常用于:交互式使用)
ChannelExec
对于ChannelExec,在调用connect()方法之前这个命令提供了setCommand()方法,并且这些命令作为输入将以输入流的形式被发送出去。(通常,你只能有调用setCommand()方法一次,多次调用只有最后一次生效),但是你可以使用普通shell的分隔符(&,&&,|,||,; , \n, 复合命令)来提供多个命令。这就像在你本机上执行一个shell脚本一样(当然,如果一个命令本身就是个交互式shell,这样就像ChannelShell)
明显:使用命令通道ChannelShell更容易,因为您不需要处理命令提示符。
ChannelShell的使用步骤
一、导入依赖
<dependency> <groupId>com.jcraft</groupId> <artifactId>jsch</artifactId> <version>0.1.54</version> </dependency>
二、实现连接
2.1 连接
public class JSchUtil { private String ipAddress; //主机ip private String username; // 账号 private String password; // 密码 private int port; // 端口号 Session session; public JSchUtil(String ipAddress, String username, String password, int port) { this.ipAddress = ipAddress; this.username = username; this.password = password; this.port = port; } /** * 连接到指定的ip */ public void connect() { try { JSch jsch = new JSch(); if (port < 0 || port > 65535){ //连接服务器,如果端口号错误,采用默认端口 session = jsch.getSession(username, ipAddress); }else { session = jsch.getSession(username, ipAddress, port); } //设置登录主机的密码 session.setPassword(password); //如果服务器连接不上,则抛出异常 if (session == null) { throw new Exception("session is null"); } //设置首次登录跳过主机检查 session.setConfig("StrictHostKeyChecking", "no"); //设置登录超时时间 session.connect(3000); } catch (Exception e) { log.error(e.getMessage(),e); } } }
2.2 执行命令(交互式)
/** * 执行相关的命令(交互式) * @param command * @return */ public int execute(String command) throws IOException { int returnCode = 0; ChannelShell channel = null; PrintWriter printWriter = null; BufferedReader input = null; Vector<String> stdout = new Vector<>(); try { //建立交互式通道 channel = (ChannelShell) session.openChannel("shell"); channel.connect(); //获取输入 InputStreamReader inputStreamReader = new InputStreamReader(channel.getInputStream()); input = new BufferedReader(inputStreamReader); //输出 printWriter = new PrintWriter(channel.getOutputStream()); printWriter.println(command); printWriter.println("exit"); printWriter.flush(); log.info("The remote command is: "); String line; while ((line = input.readLine()) != null) { stdout.add(line); System.out.println(line); } } catch (Exception e) { log.error(e.getMessage(),e); return -1; }finally { printWriter.close(); input.close(); if (channel != null) { //关闭通道 channel.disconnect(); } } return returnCode; } public void close(){ if (session != null) { session.disconnect(); } }
2.3 上传文件
/* * 上传文件到SFTP服务器 * uploadDire 上传到的服务器文件夹 * uploadFileName 上传后的文件名 lala_new.txt * localFileName D:\lala_upload.txt */ public void sftpput(String uploadDire,String uploadFileName,String localFileName) { Channel channel = null; try { //创建sftp通信通道 channel = (Channel) this.session.openChannel("sftp"); channel.connect(1000); ChannelSftp sftp = (ChannelSftp) channel; //进入服务器指定的文件夹 sftp.cd(uploadDire); //列出服务器指定的文件列表 // Vector v = sftp.ls("/"); // for(int i=0;i<v.size();i++){ // System.out.println(v.get(i)); // } //以下代码实现从本地上传一个文件到服务器,如果要实现下载,对换以下流就可以了 OutputStream outstream = sftp.put(uploadFileName); InputStream instream = new FileInputStream(new File(localFileName)); byte b[] = new byte[1024]; int n; while ((n = instream.read(b)) != -1) { outstream.write(b, 0, n); } outstream.flush(); outstream.close(); instream.close(); } catch (Exception e) { e.printStackTrace(); } finally { session.disconnect(); channel.disconnect(); } }
2.4 下载文件
/* * 从SFTP服务器下载文件 * @param ftpHost SFTP IP地址 * @param ftpUserName SFTP 用户名 * @param ftpPassword SFTP用户名密码 * @param ftpPort SFTP端口 * @param ftpPath SFTP服务器中文件所在路径 格式: ftptest/aa * @param localPath 下载到本地的位置 格式:H:/download * @param fileName 文件名称 */ public void downloadSftpFile(String ftpPath, String localPath, String fileName) throws JSchException { String ftpHost = this.ipAddress; String ftpUserName = this.username; String ftpPassword = this.password; int ftpPort = this.port; Session session = null; Channel channel = null; JSch jsch = new JSch(); session = jsch.getSession(ftpUserName, ftpHost, ftpPort); session.setPassword(ftpPassword); session.setTimeout(100000); Properties config = new Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config); session.connect(); channel = session.openChannel("sftp"); channel.connect(); ChannelSftp chSftp = (ChannelSftp) channel; String ftpFilePath = ftpPath + "/" + fileName; String localFilePath = localPath + File.separatorChar + fileName; try { chSftp.get(ftpFilePath, localFilePath); } catch (Exception e) { e.printStackTrace(); } finally { chSftp.quit(); channel.disconnect(); session.disconnect(); } }