You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
389 lines
12 KiB
389 lines
12 KiB
package com.example.upsecuritydata.controller; |
|
|
|
import com.jcraft.jsch.*; |
|
import com.xxl.job.core.context.XxlJobHelper; |
|
|
|
import java.io.*; |
|
import java.util.*; |
|
|
|
|
|
public class SSHRemoteCall { |
|
|
|
private static final int DEFAULT_PORT = 30020;// 默认端口号 |
|
// 私有的对象 |
|
private static SSHRemoteCall sshRemoteCall; |
|
|
|
// 懒汉式,线程不安全,适合单线程 |
|
// public static SSHRemoteCall getInstance() { |
|
// if (sshRemoteCall == null) { |
|
// sshRemoteCall = new SSHRemoteCall(); |
|
// } |
|
// return sshRemoteCall; |
|
// } |
|
private static String ipAddress = "223.99.228.240";// ip地址 |
|
private static String userName = "root";// 账号 |
|
private static String password = "Qingniao@123!";// 密码 |
|
private int port;// 端口号 |
|
private Session session;// JSCH session |
|
private boolean logined = false;// 是否登陆 |
|
|
|
/** |
|
* 私有的构造方法 |
|
*/ |
|
private SSHRemoteCall() { |
|
} |
|
|
|
/** |
|
* 构造方法,可以直接使用DEFAULT_PORT |
|
* |
|
* @param ipAddress |
|
* @param userName |
|
* @param password |
|
*/ |
|
public SSHRemoteCall(String ipAddress, String userName, String password) { |
|
this(ipAddress, DEFAULT_PORT, userName, password); |
|
} |
|
|
|
/** |
|
* 构造方法,方便直接传入ipAddress,userName,password进行调用 |
|
* |
|
* @param ipAddress |
|
* @param port |
|
* @param userName |
|
* @param password |
|
*/ |
|
public SSHRemoteCall(String ipAddress, int port, String userName, String password) { |
|
super(); |
|
this.ipAddress = ipAddress; |
|
this.userName = userName; |
|
this.password = password; |
|
this.port = port; |
|
} |
|
|
|
// 懒汉式,线程安全,适合多线程 |
|
public static synchronized SSHRemoteCall getInstance() { |
|
if (sshRemoteCall == null) { |
|
sshRemoteCall = new SSHRemoteCall(); |
|
} |
|
return sshRemoteCall; |
|
} |
|
|
|
/** |
|
* 远程登陆 |
|
* |
|
* @throws Exception |
|
*/ |
|
public void sshRemoteCallLogin(String ipAddress, String userName, String password) throws Exception { |
|
// 如果登陆就直接返回 |
|
if (logined) { |
|
return; |
|
} |
|
// 创建jSch对象 |
|
JSch jSch = new JSch(); |
|
try { |
|
// 获取到jSch的session, 根据用户名、主机ip、端口号获取一个Session对象 |
|
session = jSch.getSession(userName, ipAddress, 22102); //22102 |
|
// 设置密码 |
|
session.setPassword(password); |
|
|
|
// 方式一,通过Session建立连接 |
|
// session.setConfig("StrictHostKeyChecking", "no"); |
|
// session.connect(); |
|
|
|
// 方式二,通过Session建立连接 |
|
// java.util.Properties; |
|
// Properties config = new Properties(); |
|
// config.put("StrictHostKeyChecking", "no"); |
|
// session.setConfig(config);// 为Session对象设置properties |
|
// session.setTimeout( );// 设置超时 |
|
// session.setConfig("StrictHostKeyChecking", "no"); |
|
Properties config = new Properties(); |
|
config.put("StrictHostKeyChecking", "no"); |
|
config.put("PreferredAuthentications", "password"); |
|
session.setConfig(config); |
|
session.connect(3000000);//// 通过Session建立连接 |
|
|
|
// 设置登陆状态 |
|
logined = true; |
|
} catch (JSchException e) { |
|
// 设置登陆状态为false |
|
logined = false; |
|
throw new Exception( |
|
"主机登录失败, IP = " + ipAddress + ", USERNAME = " + userName + ", Exception:" + e.getMessage()); |
|
} |
|
} |
|
|
|
/** |
|
* 关闭连接 |
|
*/ |
|
public void closeSession() { |
|
// 调用session的关闭连接的方法 |
|
if (session != null) { |
|
// 如果session不为空,调用session的关闭连接的方法 |
|
session.disconnect(); |
|
} |
|
|
|
} |
|
|
|
/** |
|
* 执行相关的命令 |
|
* |
|
* @param command |
|
* @throws IOException |
|
*/ |
|
public String execCommand(String command) throws IOException { |
|
InputStream in = null;// 输入流(读) |
|
Channel channel = null;// 定义channel变量 |
|
try { |
|
// 如果命令command不等于null |
|
if (command != null) { |
|
// 打开channel |
|
//说明:exec用于执行命令;sftp用于文件处理 |
|
channel = session.openChannel("exec"); |
|
// 设置command |
|
((ChannelExec) channel).setCommand(command); |
|
// channel进行连接 |
|
channel.connect(); |
|
// 获取到输入流 |
|
in = channel.getInputStream(); |
|
// 执行相关的命令 |
|
String processDataStream = processDataStream(in); |
|
// 打印相关的命令 |
|
return processDataStream; |
|
} |
|
} catch (JSchException e) { |
|
e.printStackTrace(); |
|
} catch (IOException e) { |
|
e.printStackTrace(); |
|
} catch (Exception e) { |
|
e.printStackTrace(); |
|
} finally { |
|
if (in != null) { |
|
in.close(); |
|
} |
|
if (channel != null) { |
|
channel.disconnect(); |
|
} |
|
} |
|
return null; |
|
} |
|
|
|
/** |
|
* 对将要执行的linux的命令进行遍历 |
|
* |
|
* @param in |
|
* @return |
|
* @throws Exception |
|
*/ |
|
public String processDataStream(InputStream in) throws Exception { |
|
StringBuffer sb = new StringBuffer(); |
|
BufferedReader br = new BufferedReader(new InputStreamReader(in)); |
|
String result = ""; |
|
try { |
|
while ((result = br.readLine()) != null) { |
|
sb.append(result); |
|
// System.out.println(sb.toString()); |
|
} |
|
} catch (Exception e) { |
|
throw new Exception("获取数据流失败: " + e); |
|
} finally { |
|
br.close(); |
|
} |
|
return sb.toString(); |
|
} |
|
|
|
/** |
|
* 上传文件 可参考:https://www.cnblogs.com/longyg/archive/ / / / .html |
|
* |
|
* @param directory 上传文件的目录 |
|
* @param uploadFile 将要上传的文件 |
|
*/ |
|
public void uploadFile(String directory, String uploadFile) { |
|
try { |
|
// 打开channelSftp |
|
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp"); |
|
// 远程连接 |
|
channelSftp.connect(6000); |
|
// 创建一个文件名称问uploadFile的文件 |
|
File file = new File(uploadFile); |
|
// 将文件进行上传(sftp协议) |
|
// 将本地文件名为src的文件上传到目标服务器,目标文件名为dst,若dst为目录,则目标文件名将与src文件名相同. |
|
// 采用默认的传输模式:OVERWRITE |
|
channelSftp.put(new FileInputStream(file), directory, ChannelSftp.OVERWRITE); |
|
// 切断远程连接 |
|
channelSftp.exit(); |
|
XxlJobHelper.log("上传文件:" + file.getName()); |
|
} catch (JSchException e) { |
|
e.printStackTrace(); |
|
} catch (SftpException e) { |
|
e.printStackTrace(); |
|
} catch (FileNotFoundException e) { |
|
e.printStackTrace(); |
|
} |
|
|
|
} |
|
|
|
/** |
|
* 下载文件 采用默认的传输模式:OVERWRITE |
|
* |
|
* @param src linux服务器文件地址 |
|
* @param dst 本地存放地址 |
|
* @throws JSchException |
|
* @throws SftpException |
|
*/ |
|
public void fileDownload(String src, String dst) throws JSchException, SftpException { |
|
// src 是linux服务器文件地址,dst 本地存放地址 |
|
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp"); |
|
// 远程连接 |
|
channelSftp.connect(); |
|
// 下载文件,多个重载方法 |
|
channelSftp.get(src, dst); |
|
// 切断远程连接,quit()等同于exit(),都是调用disconnect() |
|
channelSftp.quit(); |
|
// channelSftp.disconnect(); |
|
System.out.println("下载文件:" + src); |
|
} |
|
|
|
/** |
|
* 删除文件 |
|
* |
|
* @throws SftpException |
|
* @throws JSchException |
|
*/ |
|
public void deleteFile(String directoryFile) throws SftpException, JSchException { |
|
// 打开openChannel的sftp |
|
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp"); |
|
// 远程连接 |
|
channelSftp.connect(); |
|
// 删除文件 |
|
channelSftp.rm(directoryFile); |
|
// 切断远程连接 |
|
channelSftp.exit(); |
|
System.out.println("删除文件:" + directoryFile); |
|
} |
|
|
|
/** |
|
* 如果此目录不存在将新建目录 |
|
*/ |
|
public void directory(String path) { |
|
// 打开openChannel的sftp |
|
ChannelSftp channelSftp = null; |
|
try { |
|
channelSftp = (ChannelSftp) session.openChannel("sftp"); |
|
// 远程连接 |
|
channelSftp.connect(6000); |
|
// 切换到主目录 |
|
// channelSftp.cd("/"); |
|
} catch (JSchException e) { |
|
throw new RuntimeException(e); |
|
} |
|
|
|
String[] folders = path.split("/"); |
|
for (String folder : folders) { |
|
if (folder.length() > 0) { |
|
try { |
|
channelSftp.cd(folder); |
|
// XxlJobHelper.log("切换目录" + folder); |
|
} catch (SftpException e) { |
|
try { |
|
channelSftp.mkdir(folder); |
|
XxlJobHelper.log("生成目录" + folder); |
|
channelSftp.cd(folder); |
|
} catch (SftpException ex) { |
|
throw new RuntimeException(ex); |
|
} |
|
} |
|
} |
|
} |
|
// channelSftp.disconnect(); |
|
} |
|
|
|
|
|
/** |
|
* 列出目录下的文件 |
|
* |
|
* @param directory 要列出的目录 |
|
* @return |
|
* @throws SftpException |
|
* @throws JSchException |
|
*/ |
|
public Vector listFilesBack(String directory) throws JSchException, SftpException { |
|
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp"); |
|
// 远程连接 |
|
channelSftp.connect(); |
|
// 显示目录信息 |
|
Vector ls = channelSftp.ls(directory); |
|
|
|
Iterator iterator = ls.iterator(); |
|
|
|
Map<String, File> fileMap = new HashMap<>(); |
|
|
|
try { |
|
|
|
while (iterator.hasNext()) { |
|
ChannelSftp.LsEntry file = (ChannelSftp.LsEntry) iterator.next(); |
|
//文件名称 |
|
String fileName = file.getFilename(); |
|
System.out.println(fileName); |
|
//todo 这里可使用if或正则不下载一些文件 |
|
InputStream inputStream = channelSftp.get(directory + fileName); |
|
if (inputStream != null) { |
|
File newFile = new File(fileName); |
|
//将InputStream转File |
|
// FileUtils.copyToFile(inputStream, newFile); |
|
fileMap.put(fileName, newFile); |
|
} |
|
} |
|
|
|
} catch (Exception e) { |
|
e.printStackTrace(); |
|
} finally { |
|
// 切断连接 |
|
channelSftp.exit(); |
|
} |
|
|
|
return ls; |
|
} |
|
|
|
/** |
|
* 列出目录下的文件 |
|
* |
|
* @param directory 要列出的目录 |
|
* @return |
|
* @throws SftpException |
|
* @throws JSchException |
|
*/ |
|
public List<String> listFiles(String directory) throws JSchException, SftpException { |
|
ChannelSftp channelSftp = (ChannelSftp) session.openChannel("sftp"); |
|
// 远程连接 |
|
channelSftp.connect(); |
|
// 显示目录信息 |
|
Vector ls = channelSftp.ls(directory); |
|
|
|
|
|
Iterator iterator = ls.iterator(); |
|
|
|
try { |
|
ArrayList<String> list = new ArrayList<>(); |
|
while (iterator.hasNext()) { |
|
ChannelSftp.LsEntry file = (ChannelSftp.LsEntry) iterator.next(); |
|
//文件名称 |
|
String fileName = file.getFilename(); |
|
//移除上级目录和根目录:"." ".." |
|
if (".".equals(fileName) || "..".equals(fileName)) { |
|
continue; |
|
} |
|
list.add(fileName); |
|
} |
|
return list; |
|
} catch (Exception e) { |
|
e.printStackTrace(); |
|
} finally { |
|
// 切断连接 |
|
channelSftp.exit(); |
|
} |
|
return null; |
|
} |
|
|
|
|
|
}
|
|
|