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 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 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 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; } }