java这边没有很好的封装工具连接ssh,jsch使用起来只是略微方便一点,使用的时候可以封装成工具自己使用
jsch有2种方式和客户端进行交互==ChannelShell和ChannelExec
ChannelShell和ChannelExec区别?
参考:
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();
}
}